Shop OBEX P1 Docs P2 Docs Learn Events
Serial in Assembly Code Review — Parallax Forums

Serial in Assembly Code Review

lboucherlboucher Posts: 139
edited 2010-05-04 23:57 in General Discussion
Hi Guys

·· I was hoping to ask those wiser than me to take a look at my code real quick.
You may remember this code from back near Christmas.
This is the firmware to my 17 channel SX christmas light controller.

I built 6 units, and they are all connected together via a serial line.
Computer-> Unit 1 -> Unit 2 etc...

Anyways
So i "borrowed" the interrupt based assembly level serial.
I generally understand how it works, but not clear enough to really debug.

The quick funtional overview.
Each box receives serial data.
The start of the serial data is always 126 (Sync Byte) followed by a byte i don't care about.
Then 17 dimmer levels for that particular unit.
Then more dimmer levels for units downstream.

The Sync Byte, Byte I don't care about, and dimmer bytes after the first 17 received, all get repeated downstream.


There were 2 issues i discovered once i fielded the system.
1. From the 3rd unit on the data was corrupt resulting in random flashing.
(Workaround was to set computer to use 2 stop bits instead of 1.)
2. From the 2/nd or 3rd box down i would get random flashes when the dimmer value was really low, say 30 or below.
(Workaround, don't send really low dimmer values.)

So overall, it worked fine this past year. These 2 things just bug me, i spent a couple hours looking at the code and still don't get it. If i am reading the code right this should definitly work with only 1 stop bit.

Any thoughts would be appreciated.

Thanks

Comments

  • ZootZoot Posts: 2,227
    edited 2010-05-02 23:30
    Some of what you describe sounds like it might be noise on the lines. But looking at the flow of your main program, there is nothing to prevent a dimmer level value of 126 to be mistaken for a new sync byte:

    IF working_byte = 126 THEN
    byte_count = 1
    \mov tx_high,working_byte
    \clrb tx_low.7         ' set start bit
    \mov tx_count,#10     '1 start + 8 data + 1 stop bit
    ELSE
    INC byte_count
    ENDIF
    
    



    I would either capture all relevant bytes to a buffer, then parse the relevant bytes once I have them all, or use a simple state machine. You could use the status of byte_count, a la:

    IF byte_count = 0 THEN    ' only check once for a packet
      IF working_byte = 126 THEN
      byte_count = 1
      \mov tx_high,working_byte
      \clrb tx_low.7         ' set start bit
      \mov tx_count,#10     '1 start + 8 data + 1 stop bit
      ENDIF
    ELSE
      INC byte_count
    ENDIF
    
    IF byte_count = 2 THEN
      \mov tx_high,working_byte
      \clrb tx_low.7         ' set start bit
      \mov tx_count,#10     '1 start + 8 data + 1 stop bit
    ENDIF
    
    IF byte_count = 3 THEN ' as before
    '...
    ENDIF
    
    ' now this part I don't get -- how would byte_count ever be larger than 19 unless it's a new packet? 
    ' seems like the tx'ed byte should be sent on byte_count = 19 (the last byte of the packet)
    ' additionally, we want to set the byte_count back to 0 to trigger a wait for the sync
    
    IF byte_count = 19 THEN
      READ Scurve+working_byte, Level17
    ENDIF
    
    IF byte_count >= 19 THEN
    \mov tx_high,working_byte
    \clrb tx_low.7         ' set start bit
    \mov tx_count,#10     '1 start + 8 data + 1 stop bit
      byte_count = 0
    ENDIF
    
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    When the going gets weird, the weird turn pro. -- HST

    1uffakind.com/robots/povBitMapBuilder.php
    1uffakind.com/robots/resistorLadder.php
  • lboucherlboucher Posts: 139
    edited 2010-05-03 00:09
    Hi

    Thanks for the responce.
    126 is handled by the software on the computer.
    The computer will never send the value 126 unless it is a Sync Byte
    This is part of the renard protocol.

    As for bytes past dimmer 17.
    My setup works a bit different than others.
    A "Packet" in my setup is:
    1 Sync, 1 other byte, and (17 * 6) dimmer values for a grand total of 104 bytes.
    (The other byte is a part of the Renard protocol i don't use.)

    So 104 bytes come out of the computer ever "Event"
    The first unit receives all 104 bytes, strips off the first 17 dimmer values and sends everything else downstream.
    So the 2nd unit sees 87 bytes, and on and on until the last unit only sees 19 bytes.
    (Make more sense, i did a horrible job describing that in the first post.)

    Overall i feel pretty confident about everything except the assembly code.
    You might be very correct about noise, i am sending ttl level serial unshielded over sprinkler wire >30 feet.
    Bad i know, but it worked and was super cheap.
    It just seemed odd that noise would show up in such a pecular fashion. I would expect noise to be a persisten problem regarless of number of stop bits, or dimmer value sent.

    If no one points out an issue in the assembly i am thinking i will hack off all the excess length on the cables i can for next year and see what happens. Probably re-program all the chips to, just to make sure i have the exact some firmware on each.
  • ZootZoot Posts: 2,227
    edited 2010-05-03 03:05
    Try a much slower baud rate. That seems awfully fast for a such long run.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    When the going gets weird, the weird turn pro. -- HST

    1uffakind.com/robots/povBitMapBuilder.php
    1uffakind.com/robots/resistorLadder.php
  • JonnyMacJonnyMac Posts: 8,927
    edited 2010-05-03 12:40
    I'm certain its not an issue with the firmware serial receiver; I've used that same code for baud rates up to 250K and it works fine. The will be a lot of electrical noise in a Christmas display, especially with triacs firing at any point in the AC cycle. You could try to route your comms wiring away from AC and keep it as short as possible. Are you using RS-485? This would seem to make the system more noise-immune.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon McPhalen
    Hollywood, CA
  • lboucherlboucher Posts: 139
    edited 2010-05-03 14:37
    Ya, should have used rs-485 but i was trying to go super cheap.
    Will try shortening my runs and going with a lower baud rate this coming december.

    Thanks.
    ·
  • PJMontyPJMonty Posts: 983
    edited 2010-05-04 23:57
    lboucher,

    RS-485 is super cheap. The parts cost a few bucks and there are versions that run on 5v and 3.3v. It's great stuff. Whatever you spent on triacs dwarfs the tiny additional cost of an RS-485 transceiver.

    Thanks,
    PeterM
Sign In or Register to comment.