Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

UART Code help: Motor Control

Status
Not open for further replies.

Vizier87

Active Member
Hi guys, I wrote this code, where basically I'm only trying to control a motor using a L293 by transmitting RF data via UART. One direction worked perfect for reading 0xFF, but the other direction turn doesn't work with 0xAA matched to the receiver.

Here's the transmitter code (MikroC):

C:
while (1){

     if (Left==1){              // Just a designation for a pin, which is an input, for "left" 
                                       // as anti-clockwise data
       rb7_bit=1;
       UART1_Write(0xff);

     }

     else if (Right==1){     // "Right" as clockwise data
       rb7_bit=1;
       UART1_Write(0xaa);

     }
     
     else {
          UART1_Write(0x00);
          rb7_bit=0;
          }
     
   }

And this is the receiver:

C:
while (1) {

    if (UART1_Data_Ready()==1) {     // If data is received,
      x_=UART1_Read();
    }

    else if (x_==0xff){
       rd6_bit=0;   // clockwise (worked fine at the receiver's end)
       rd5_bit=1;
     }

    else if (x_==0xaa){
       rd6_bit=1;     //anti-clockwise (supposedly, but didn't work)
       rd5_bit=0;
     }
     
    else portd=0;

}

I set the baud rate as per the specs of the RF module, and the data transmission for matching the value 0xFF between the receiver and transmitter worked pretty well. The problem is the other direction, and I suspect my code is shabby.

Really appreciate the time spent on this.

Cheers.
Vizier87.
 
Last edited:
I'm assuming these are one of those "dumb" receiver/transmitter modules. If that's the case, using these with an unmodified UART is flaky. There is code out there for manchester encoding or two-byte-> three byte encoding to balance the data so you aren't sending too much '1's. The minimum you can do is invert the signal so the uart signal is backwards (high when it should be low and vice versa) this cancels out the issue that UART serial holds the dataline high when not in use.

Personally I've used the virtualwire library for the Arduino. It's easy to port to other microcontrollers and just needs a timer to hook into.

You might want to move to the digital transceivers, though. They're cheaper, but they can be a bit of a pain to setup. Once you have a library they are easy to manage and the library can move to different microcontrollers easily. Standard SPI.
 
I can't see how it works properly at all..

If data then x =read

Elseif x== 0xFF /// Cant see this working...

Code:
while (1) {

    if (UART1_Data_Ready()==1) {     // If data is received, "If not carry on!!!"
      x_=UART1_Read();
    }
 
    if (x_==0xff){
       rd6_bit=0;   // clockwise (worked fine at the receiver's end)
       rd5_bit=1;
     }
 
    else if (x_==0xaa){
       rd6_bit=1;     //anti-clockwise (supposedly, but didn't work)
       rd5_bit=0;
     }
 
    else portd=0;
 
Mr Ian is right . What you wrote there was if () elseif() which means, if data is ready, there is no need attending to the else statement. U can use another if statement instead of elseif
 
Ha, I didn't even look at the code. I would modify Ian's code though as his works on x even if no data is ready and x hasn't been read. All of the processing of x should be within the first if.
 
I'm assuming these are one of those "dumb" receiver/transmitter modules. If that's the case, using these with an unmodified UART is flaky. There is code out there for manchester encoding or two-byte-> three byte encoding to balance the data so you aren't sending too much '1's. The minimum you can do is invert the signal so the uart signal is backwards (high when it should be low and vice versa) this cancels out the issue that UART serial holds the dataline high when not in use.

Personally I've used the virtualwire library for the Arduino. It's easy to port to other microcontrollers and just needs a timer to hook into.

You might want to move to the digital transceivers, though. They're cheaper, but they can be a bit of a pain to setup. Once you have a library they are easy to manage and the library can move to different microcontrollers easily. Standard SPI.

Yup, it is a 315MHz transceiver, and heck noisy. But the tech guys who manufactured them told that it can be rectified via software. So I decided to give it a shot. But it is digital already. The reason I'm resorting to this is they're what I have. My Xbees got fried recently, and was a costly lesson to learn.

Perhaps I'll purchase these later, they're said to be replacement for the Xbees at a much lower price?
 
I can't see how it works properly at all..


Code:
while (1) {

    if (UART1_Data_Ready()==1) {     // If data is received, "If not carry on!!!"
      x_=UART1_Read();
    }
 
    if (x_==0xff){
       rd6_bit=0;   // clockwise (worked fine at the receiver's end)
       rd5_bit=1;
     }
 
    else if (x_==0xaa){
       rd6_bit=1;     //anti-clockwise (supposedly, but didn't work)
       rd5_bit=0;
     }
 
    else portd=0;

Thanks for the correction. I toldya, my coding is still shabby. :D
I do need to have my fundamentals polished.
 
Mr Ian is right . What you wrote there was if () elseif() which means, if data is ready, there is no need attending to the else statement. U can use another if statement instead of elseif

That is just me trying things at random to see if it worked. The thing is, for the case when I use switches input into the PIC's pins, like this program down here:

C:
while (1){
   
   if (rc0_bit==1){
     rd6_bit=1;
     rd5_bit=0;

   }
   
    if (rb5_bit==1){      // comment below will be regarding this clause of the program
     rd6_bit=0;
     rd5_bit=1;

   }
   
   else portd=0;
 }

Referring to the code wrap up here, when the program is like this, the motor does NOT turn. Later I checked using a scope, and it showed the oscillation at an extremely high frequency between ON & OFF for this routine. Adding "else" to that line remedied it immediately. And yes, I've pulled my input pins of the switch LOW sufficiently.
 
Last edited:
Use the "virtualwire library for the Arduino" as Mark Higgins said It's easy to port.

It fixes the noise them 315 pick up everything light bulb over my table LOL. but it fixed that still could toggle a light at 20 feet with a set.


I also used Uart but you can't send it fast about 2400 is as fast as you can send.

See the keying has to be long enough to hold the signal so you don't get noise you go faster then 2400 baud it all looks like noise.
 
Last edited:
I think it's to do with the auto gain int he receiver, you should send a preamble of 2 or 3 bytes so the receiver sets the gain right, then send the data bytes.

With the data bytes you can still use the serial UART data but split one data byte into two 4bit chunks, then send each 4 bit chunk as one byte, by inverting each bit;
so if the 4bit chunk is 0001
send; 01 01 01 10 as a byte

that is a like a cheat form of "manchester encoding" that ensures every byte sent has an equal number of 0 and 1 bits, that keeps the biasing and auto gain in the receiver working right.
 
I think it's to do with the auto gain int he receiver, you should send a preamble of 2 or 3 bytes so the receiver sets the gain right, then send the data bytes.

With the data bytes you can still use the serial UART data but split one data byte into two 4bit chunks, then send each 4 bit chunk as one byte, by inverting each bit;
so if the 4bit chunk is 0001
send; 01 01 01 10 as a byte

that is a like a cheat form of "manchester encoding" that ensures every byte sent has an equal number of 0 and 1 bits, that keeps the biasing and auto gain in the receiver working right.

Thanks for the input Mr RB, I'm going through the library on Manchester encoding in MikroC and see where I can go from here.

On the other hand, it is a tad bit complex than UART! XD
 
Vizier87 uart will work fine at slow baud of 2400 and invert it, Only time you'll have any problems is when there are more them one transmitter in range but you can deal with even that.

Just send a id byte then data then a end byte so you basically end up with a homegrown form of manchester.

MrRb you hit the nail on the head that's the problem Inverting really helps and I have done code like your saying a form of manchester it works fine as long as the keying is long enough to keep the receiver from picking up noise.
 
Last edited:
Yep! Keep the baud at 1200-2400 range, and use the UART with any type of data encoding you like where there are roughly as many 0 and 1 bits, and not too many in a row.

You might be able to get away with transmitting raw UART data but a byte like 0xFF will transmit only as a single start bit, followed by 9 or more transmitter off bits, which can mess up the gain of the receiver. Sending 4bits with an inversion means you can use the simplicity of the UART send and get all the benefits of manchester.

It's also easy for error detection as the received byte must follow that rule of inverted bit pairs.
 
Here a pic there labeled first one noise second one is what turned on the lights third one turn them off it worked fine
total+test.PNG

Guess attachments still don't work
 

Attachments

  • total test.PNG
    0 bytes · Views: 0
Last edited:
Status
Not open for further replies.

Latest threads

Back
Top