UART receiver program only works when I retransmit received data!

Go To Last Post
16 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hey there nice people..

I'm new here and happy to ask my first question :)

My project consists of a transmitter and a receiver, the transmitter is an ATmega16a, it reads the position of a joy stick and sends it using UART over radio signals

the radio module used is a 433 MHz module (FS1000A)

The receiver (which is also an ATmega16A) lights an LED  based on the position of the joystick

My code is written in Assembly, no libraries were used

Here's the strange thing, when my code didn't work I added some code to re transmit every received byte of data so I can view it on my PC and make sure the uC received the data properly

And because of that bit of code the program works! when I comment out that part it doesn't work

Can anyone explain why?

Both receiver and transmitter programs are attached

 

 

Attachment(s): 

This topic has a solution.
Last Edited: Mon. Jul 6, 2020 - 11:44 PM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Welcome to AVRFreaks!

 

You can find lots of useful info in the tutorial forum here, start with this first post and see if it helps you.

https://www.avrfreaks.net/forum/...

 

Jim

 

 

(Possum Lodge oath) Quando omni flunkus, moritati.

"I thought growing old would take longer"

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

owam96 wrote:
sends it using UART over radio signals

does it work without the radios, ie. hardwired serial connections?

 

Jim

 

 

(Possum Lodge oath) Quando omni flunkus, moritati.

"I thought growing old would take longer"

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No, just tried the hardwired method, it doesn't work.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok, read the reference above about how to solve one problem at a time, at this point, you need to trouble shoot one end (TX or RX) first, get it working 100%, then work on the other end.

Once you have both ends working correctly, then get them to talk to each other over the hardwire link.   Then try the radio's, which depending on the radio used, adds a whole new level of problems.

 

Jim

 

 

(Possum Lodge oath) Quando omni flunkus, moritati.

"I thought growing old would take longer"

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The problem turned out to be very simple, part of the code is a block that I copy and paste and then change some lines in it.

In some blocks that I copied and pasted I forgot to change some lines.

On why it worked when I put that transmitting code, I have some vague idea, it's something that has to do with timing.

Anyways, thanks for the advice, good trouble-shooting habits always work.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Firstly, the code you posted is near unreadable. My first suggestion is to format it so the reader gets an idea of the the flow and structure. I'm used to reverse engineering code and this is one of the first things I do. 

 

You've determined that adding the extra code makes it work. Obviously it changes something. There's the assumption that the problem is in the code - how do you know this? Maybe the effect of hooking it up to the PC changes something in the hardware? Maybe the voltage to the micro changes and alters the internal oscillator frequency? Without any further evidence you might just stare at the code all day and not solve anything. Or you could be lucky and there's a simple code error. For this situation an oscilloscope of logic analyser is invaluable. Get yourself a Salaea Logic or clone. The clones are around $8usd out of China. With one of these you can make measurements and narrow down the problem quick smart. Other options are the sound card in your PC. That makes for a simple low frequency oscilloscope. 

 

Some comments about your implementation - why use the usart? You would be better off just bit-banging the data bits. Using the usart means you have less frequency tolerance - if you are using the internal oscillator of the mega16  then expect difference between your tx and rx sides. Manchester encoding is ideal for this as it can tolerate significant frequency change. Radiohead uses a more efficient run length encoding method.

 

With the ADC - why do you use the ADIF bit? Surely the ADSC bit is the intended bit?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My first suggestion is to format it so the reader gets an idea of the the flow and structure.

Thank you for your comment, I'll try to make my code more readable in the future.

 

For this situation an oscilloscope of logic analyser is invaluable.

Yes I was recently thinking of getting a logic analyzer, I will try to get it soon.

 

You would be better off just bit-banging the data bits

I don't know what bit-banging is, but I'll start reading about it since you mentioned it and I've recently read it some where else.

 

Radiohead uses a more efficient run length encoding method.

I try to do things from scratch to walk the learning path, most of my methods are not efficient because I try to do something that just works. Once my method works I may try to use more efficient ones I learn. Not sure if this is the right way to learn but I've been somewhat enjoying it.

 

 

 

With the ADC - why do you use the ADIF bit? Surely the ADSC bit is the intended bit?

Isn't the ADIF bit set when the conversion is complete? I'm polling it to wait for a complete conversion.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

'bit banging' is simply writing the code to send/receive the bits rather than using the usart. Using the usart in your application is a bad idea.

 

The ADIF is the adc interrupt flag. Whilst it can be used, you need to clear it. The ADSC flag doesn't require this extra step. What does the datasheet say?

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Oh ok, so I do it in software instead of using the usart peripheral. Good to know. But I imagine it would be very hard to do.

I only use the adsc flag to start the conversion, I now went to the datasheet and it says "This bit stays high
as long as the conversion is in progress and will be cleared by hardware when the conversion is completed"
So now I can see that it can also be used to know when conversion is complete, thanks :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What is hard about setting/clearing a bit,delay etc? All in a day's work for an assembler programmer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

owam96 wrote:
I'll try to make my code more readable in the future.

Also see Tip #1 in my signature (below)  for how to properly put code into  a post.

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

note you do a send , then you check next char for busy (you are assuming first char not busy----bad!!!)

 

BREQ END_OF_PREAMBLE
OUT UDR, GREG1         -----what if busy from previous call??
CHECK1: IN GREG1, UCSRA

 

Always check for busy, even first time, before send.    You call this routine over & over as well 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you for the advice, so I should do it like this, correct?:

BREQ END_OF_PREAMBLE
CHECK0: IN GREG2, UCSRA
SBRS GREG2, UDRE
RJMP CHECK0
OUT UDR, GREG1

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

check for the busy flag,

   if busy keep checking busy flag 

check for data to send,

    if none, exit

 send data

 back to check for busy flag

 

check the busy flag first, not last

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I did this in assembler about 10 years ago, it may give you some ideas about bit-banging.

Using the usart was totally unreliable with these RF modules.

Back in those days, I couldn't find any hardware encoder/decoders in stock anywhere so I did it with software.

 

Software RF Encoder/Decoder

 

The transmitter and receiver were about 300' apart from each other and the system was very reliable with the RF modules I was using.

I use the same encoder/decoder pair for another application in my home, still working reliably from the basement all the way to the top level of my two storey home.

 

 Of course, you may have to fine tune the receiver code with different RF receivers. Absolutely you need a logic analyzer.

If you can't afford one, there are affordable ones on ebay and some clones as well usually under $10.