UART Transmission with atmega328p

For general Flowcode discussion that does not belong in the other sections.
ChrisT66
Posts: 103
http://meble-kuchenne.info.pl
Joined: Mon Dec 07, 2020 12:47 pm
Been thanked: 1 time

Re: UART Transmission with atmega328p

Post by ChrisT66 »

Your suggestion to use the checksum is perhaps a good idea. I have read that all transmitted bytes are subtracted from 0xFFFF. With a 6-channel receiver, for example, the remaining channels (i.e. 8) are filled with 0x05DC. But only the sender knows the exact data of the 6 channels it is sending and can check the checksum, or am I making a mistake?

mnfisher
Valued Contributor
Posts: 1628
Joined: Wed Dec 09, 2020 9:37 pm
Has thanked: 142 times
Been thanked: 761 times

Re: UART Transmission with atmega328p

Post by mnfisher »

It would 'normally' be transmitted as the last 2 bytes of the message - and should be correct for the packet to be valid.

Should be possible to check using a downloaded packet - if it's just a subtraction then all should be well - some checksum use a CRC and life would be harder unless the docs give a clue.

ChrisT66
Posts: 103
Joined: Mon Dec 07, 2020 12:47 pm
Been thanked: 1 time

Re: UART Transmission with atmega328p

Post by ChrisT66 »

That means I have to subtract the 6 words of the 6 received channels from 0xFFFF, then subtract 8 times 0x05DC for the unused channels and then compare that with the last word (the checksum), right?

mnfisher
Valued Contributor
Posts: 1628
Joined: Wed Dec 09, 2020 9:37 pm
Has thanked: 142 times
Been thanked: 761 times

Re: UART Transmission with atmega328p

Post by mnfisher »

Well worth a try - it might also include the header as well.

What values do you receive on the unused channels (ie do you get 0x05DC or 'random' values)
If it works - easy to do in a loop in the code.

ChrisT66
Posts: 103
Joined: Mon Dec 07, 2020 12:47 pm
Been thanked: 1 time

Re: UART Transmission with atmega328p

Post by ChrisT66 »

Yes exactly, the unused channels always deliver 0x05DC.
You just have to think about what kind of receiver you have, 6 or 8 channel etc.

Another stupid question: when do you use parameters and when do you use variables? You have also defined parameters in your chart. I haven't used them yet.

mnfisher
Valued Contributor
Posts: 1628
Joined: Wed Dec 09, 2020 9:37 pm
Has thanked: 142 times
Been thanked: 761 times

Re: UART Transmission with atmega328p

Post by mnfisher »

I would always favour local variables (and function parameters) over global variables. Global variables are sometimes a necessary evil (for example for the interrupt handler). If you create a large program then it makes life much simpler and avoids many possible errors.
It's worth splitting your program into small (hopefully) easily understood functions - the overhead is very small to use them

Where possible functions should avoid having side effects - they can (and will) come back to bite you at some stage with a weird crash.

mnfisher
Valued Contributor
Posts: 1628
Joined: Wed Dec 09, 2020 9:37 pm
Has thanked: 142 times
Been thanked: 761 times

Re: UART Transmission with atmega328p

Post by mnfisher »

A quick thought on checksums after some googling.

As far as I can tell - the value (the last two bytes of the packet) should match 0xFFFF - each byte of the packet (including 0x2040 but excluding the checksum) (Note the first byte is actually a packet length (0x20) then a command (only 0x40 supported)

Then I think we could refactor slightly.

The Rx interrupt could calculate the checksum as well as calculating the channel values:

We know the current position (so 0 is LSB of channel 0)

So something like (thinking aloud):
(in the interrupt handler)

Code: Select all

(case 1)
   csum = 0xFFFF - 0x20 - 0x40 
(case 2)
if pos < 28                         // Data in bytes 0..27
    csum = csum - .c
    channel = pos / 2           // 0 and 1 = channel 0, 2 and 3 = channel 1...
    if channel < 6                // We have channels 0..5
	if (pos & 1)   == 0      // Even byte is LSB
		data[channel] = .c
	else
   		data[channel] = data[channel] + (.c << 8)
if pos = 28                         // LSB of checksum
    checksum = .c
if pos = 29                         // MSB of checksum
   checksum = checksum  + (.c << 8)
 
I've attempted to implement this (please post a few 'full' data rows - for testing.)

Maybe also need to add a timeout - connection lost?

Martin
Attachments
IBUS4.fcfx
(26.24 KiB) Downloaded 132 times

ChrisT66
Posts: 103
Joined: Mon Dec 07, 2020 12:47 pm
Been thanked: 1 time

Re: UART Transmission with atmega328p

Post by ChrisT66 »

Wow, thanks for your new idea.
Nothing is currently displayed, i.e. the programme is stuck somewhere. I'll have to see if I can find something.

mnfisher
Valued Contributor
Posts: 1628
Joined: Wed Dec 09, 2020 9:37 pm
Has thanked: 142 times
Been thanked: 761 times

Re: UART Transmission with atmega328p

Post by mnfisher »

Okay - does that mean the checksum test is failing?

ChrisT66
Posts: 103
Joined: Mon Dec 07, 2020 12:47 pm
Been thanked: 1 time

Re: UART Transmission with atmega328p

Post by ChrisT66 »

Yes, it hangs in the query If pos < 28

Post Reply