Atom Pro serial IO (S_IN/SOUT) and IRQ0

Suppose that I have a VB application (or could be some other application on a PC) that I want to send a packet of information from the PC to the Pro at some random time. In my case I may have my over VB sequencer and when the user does something I want to tell my Brat about it. The problem that I run into is that there is no hardware support built into the Pros handling the serial IO for the main serial IO port (S_IN, S_OUT). So unless the Atom Pros code is sitting in a SERIN statement, the input is lost. The problem is that I don’t always want my my brat sitting around waiting for input from the PC. It has to also do things like receive commands from the TV remote, walk, etc.

So I have been trying out different approaches. None of them have been as reliable as I would like. I am in the process of trying out a different approach, that I am not sure will work or not. This is sort of hard to explain, but I will try:

It is my understanding that both S_IN and S_OUT are connected to P14 by a diode half duplex circuit. This is from the thread:
lynxmotion.net/viewtopic.php?t=2597&highlight=diode

On the H8/3694 P14 is the pin for IRQ0, which AcidTech mentioned in a different thread:lynxmotion.net/viewtopic.php?t=3417&highlight=irq0 My guess is this is not by accident.

So a thought came to mind. Could my Pro basic program set an interrupt handler for IRQ0. I would guess that I would have to setup a few H8 IO registers, like probably set bit4 in PMR1 to tell the H8 that that IO pin is for an interrupt and not general IO. Likewise I would probably need to set bit 0 of IEGR1 to say I want the interrupt on the leading edge.

My idea is to setup the IRQ0 interrupt on the PRO.

On the PC side have my prgram output one byte of 0xff. with the inversion I believe that I will get an upspike for the start bit and then all of the databits and stop bit will show as a low voltage.

Now if I can at that point get the Atom Pro code to process that as an interrupt. I would then switch the pin back to being standard IO and try to do a serin of the packet of information. On the PC side I would delay a short time after outputing the 0xff and then output the packet. Assuming all of this works, the Pro would send back some form of Ack to the PC.

I have hacked up my first attempt at this and so far my interrupt handler has not been called. A thought came to mind that maybe the inverted signals that I have been seing at the external SIN/SOUT pins of the pro are inverted from the signals that are actually on the H8 P14 pin. So I will try experimenting and maybe interrupt on the other edge. I don’t think this will help as the input on the line generates both edges, but what the heck…

Suggestion? I will probably directly email acidtech as well.

Kurt

That’s what I was going to suggest when I started to read your email. It should be practical. In fact, you can probably just leave the interrupt on, while reading the data. Just don’t clear it until after reading the string or whatever. I’d send AA or 55 or some mix. Trigger on any edge. You could even wait for a pair of interrupts to qualify a message coming in. And no delay after the trigger byte should be necessary, I suspect.

Alan KM6VV

Thanks Alan,

Last night I think I was able to get the interrupt to be at least called. I also needed to also update another interrupt register:

ONINTERRUPT IRQ0INT, HANDLE_IRQ0 PMR1.bit4 = 1 ; enable pin to IRQ0 interrupt instead of normal I/O IEGR1.bit0 = 1 ; Interrupt IRQ0 on rising edge enable irq0 ienr1.bit0 = 1

In the interrupt I: low p5

And now the light does come on on my old ABB board. So now I just simply need to debug my input code.

What I have not decided yet is it better to have the interrupt handler do the serin commands before resume or have it simply set some variable that gets tested in my main loop and then calls off to a function to do the input. The problem of the second approach is that the brat may be in the middle of some sequence of movements and could easily be in the middle of processing some HSERVO or HSERVOWAIT commands.

One possibility is to have interrupt handler set the state variable. When the main loop processes the state. It sends some ACK back to the PC that says I am ready and then it waits for the input.

I will probably first play with the approach of reading the packet in the interrupt and then having the main loop process the interrupt when it is ready…

Kurt

Hi Kurte,

I’d just set a task flag in the interrupt. Do reading of the packet outside of the interrupt, assuming you don’t have the hardware for the USART.

Being in the middle of a sequence would certainly get in the way of communications if you don’t have the hardware USART. Just a side question, but why not? Receiving chars is the tricky part, I’d let hardware do that. I’m guessing you’re using the hardware USART to talk to an SSC32? If that’s the case, I’d suggest splitting up the USART so that the receive side (not needed by the SSC32) can be used for receiving commands. But Of course I may be missing the point and you’ve already considered all that!

The ACK plan sounds workable. Get the 'bot back to a “receptive” state.

Don’t you mean read the packet in the main, and service the interrupt in the interrupt service routine?

If you had the I/O bits, I’d almost suggest adding a hardware USART! Or perhaps a 2nd processor to handle the comm stuff! I think that’s what I’d like to do with the SPI.

Alan KM6VV

I could obviously try doing that by adding an external chip such as a MAX232 to the hardware serial port and hook up an additional serial connector. That would be somewhat easy to do and I think I still have a small breadboard sitting around with the chip and the capacitors and the like.

But that would defeat the major goal for doing that. Which is when I have this working reasonably well, I will share the setup and code, such that others could easily use it. So I am trying to keep the setup the same as the original TV Brat and maybe a few additional add-ons, like a servo for a head, where you could hook up something like a Ping or other sensor… Likewise the use of an LCD.

Currently I am a different serial LCD on my Brat, than the one they sell, but do have the one they sell on my Rover and I will probably allow the code to be configured for both…

Actually I meant to say read the packet in the interrupt, but process it in the main, mainly as a way to avoid having to send an ack… But in the end I will probably do it the other way as it is a lot cleaner! I hate doing a lot of stuff in an interrupt hander!

Thanks again
Kurt

Just a quick update. I have now had pretty good success in getting the communication to work. I now have my Brat and VB SEQ type application talking reasonably well.

When the VB application wants to communicate with brat it first sends a single byte 0xff (which as a pulse just shows up as the single start pulse. It waits for a little time to allow the Atom to prepare to receive a packet. I then try to send a packet that consists of:

On the Atom Side: I enable IRQ0 on the trailing edge. The interrupt handler simply sets a state variable. At the start of the main loop, the code checks for this state variable and then calls off to functions to receive the packet and send an Ack packet back to the PC and then processes the commands.

So far it is working well enough. I have it trying out one line of a sequence, trying out a simple sequence and downloading the sequence and storing it in the EEPROM of the on the Atom Pro. Once stored the sequence can be executed by hitting the Play button ton the TV remote…

That is all for now
Kurt

That’s great!

What format for the sequence did you choose? You might choose to do a simple “#servo Pnnn” type of format, then it’ll be compatible with LM’s SEQ. But then your initial “0xFF” byte might get in the way.

That’s not bad! Good progress.

Have you found out anything about the I2C “going dead”? I couldn’t remember what thread was that on, or I’d have asked there.

Alan KM6VV

My format is currently binary information. I send out a command as one byte. I have all of these bytes starting off with the top nibble being 0XF as one verification. My packet has a sequence number, which is currently two bytes, but could be shortended to one and then a count of extra bytes. When I download a sequence item, these extra bytes are two byte per servo in degrees +90 to -90, which fits well within one byte but I had the packet as two bytes each and two bytes for the time value. On the brat side I shortened all of these values down to one byte each. One could easily expand on this with an additional byte telling which servo…

I have not worked on this yet. For the most part this was a device problem, where the device holds either SCL or SDA low and rebooting the processor does not clear this. My thoughts were to maybe have the power pins for the I2C devices come off of a different IO pin that I can turn on or off by software to reset the bus. Not sure if I would need to add a hardware driver to no overload the IO pin or not.

Kurt

A clock or data line is still being driven, and that’s what hangs up the slave? I tried reinitializing the I2C, maybe clearing the setup more (float SCL and SDA pins?) would help.

I’m thinking of ordering another ultrasonic rangefinder SRF08 (need one anyway), and possibly trying an EEPROM. I’d like to see how they work.

Alan KM6VV

I believe tha in the I2C specs there are certain times when a slave device will hold down the SCL line low until it completes something and then lets it float. I believe this lets the master know that it is still busy. The problem I had was with a I2C LCD (Matrix Orbital GLK12232-25), that some of the time it would get confused and clamp SCL to low. The only way at the time I found to clear SCL was to turn off power and turn it back on. It has been 21/2 years ago since I tried this device out. If I remember correctly I was able to reduce how often this happened, by pausing between each character that was sent to the LCD (ie only one output byte per I2C packet). My next approach was going to be to have the power to the LCD under the processors control. So if the processor found that the bus was held down longer than expected, it would reset the device…

I have used both the SRF08 and the SRF10 and have not had this problem with them. I have not done much yet with I2C EEProms other than the EEPROM on the Atom Pro chip is internally controlled by I2C, but I have only interfaced to it through the basic commands.

Kurt

Nice work on the BRAT videos Kurt-E!

Then I am probably looking at the problem the wrong way probably. I should look to see WHO is maybe still pulling the SCL line low.

I am immediately asking for a light value after reading the range, that starts to sound like your asking for additional data… I can try removing the SRF08 power, and see if the SCL line releases, or the problem clears. Thanks for the tips!

Alan KM6VV

It is called clock-stretching and you are correct it is a way for the slave to force the master to wait. If you are bit-banging the I2C master then make sure you support the clock-stretching and meet the timing requirements when you check for it.
Be careful about noise on the SCL line as it can be mistaken as an “extra” clock and with some devices this will hang the I2C bus. Correct pull-up values and deliberate control of the capacitance on the I2C bus as well as proper signal grounding may be needed to resolve that. Electrical “robust-ness” is not a forte of I2C.
If you have to deal with noisy environments, poor ground signal handling, or ugly cable runs then see if you can find SMBus compatible I2C devices. These should include a time-out period on any transaction (23mS I think) so if you were to get the device “stuck” it will eventually time-out and let go of the bus.

Hi Eddie,

I’m running the I2C hardware of an 18F4620 PIC. So at least I don’t have to bit-bang it. I have the pullups, although I could add a little more power filtering. I’ll take a look at it with a ‘scope. Very short bus, just up to the SRF08 for now. Future plans for ‘bot controller boards (other ‘bots) will want to use multiple SRF08 rangers and other devices as well.

I do have timeouts in the I2C code, and I’ve tried to reset the I2C, but It doesn’t start up again. The I2C code doesn’t block, so the rest of the ‘bot doesn’t even know there is a problem with the I2C!

Thanks,

Alan KM6VV

Thanks Eddie,

When I had the problem with the LCD display hanging the LCD, I was using an Atmel ATmega32 chip and using the I2C(TWI) support. The code also had timeouts built into it to keep things from hanging and I did try resetting the bus and that did not help. I later mostly avoided it by not sending several bytes in a row to the display, but to build in a delay for each character displayed. This was especially true for special commands like Clear Display or the like.

One of these days I will have to dust off that LCD and try it out again on one of my Lynxmotion robots. I will probably wait until I update my I2C code to be interrupt driven…

Kurt

uh, just be advised, ATmega TWI in master mode, especially multi-master I2C, has an issue. You can find info on it on avrfreaks, but getting Atmel to actually own up to the problem seems to be another issue entirely. Their remedy to the problem is to reset your slave… not fix their bloody hardware. Twits!