Controlling a dc motor via rf links ! problem!

Transmitter_and_potentiometer.jpg (111419Bytes)
receiver_and_dc_motor.jpg (114107Bytes)

hello guys,

i am trying to control a dc motor via rf links, i tried to control it without the rf links and everything works fine with a potentiometer

but now i added the RF links and i wrote the program but it's not working can anyone help please ? (check the attachmenet files for schematics)

here are the codes :

// TRANSMITTER CODE

#include <VirtualWire.h>

int potPin = A0;
const char *motorOn = "a";   //28
const char *motorOn1 = "b"; //50
const char *motorOn2 = "c"; //100
const char *motorOn3 = "d"; //150
const char *motorOn4 = "e"; //200
const char *motorOn5 = "f"; //255

void setup()
{
  Serial.begin(9600);
  while (! Serial);
  Serial.println("Speed 0 to 255");
 
  vw_setup(2400);     // Bits per sec
  vw_set_tx_pin(12);
}
void loop()
{
  int val = map(analogRead(potPin), 0, 1023, 0, 255);
  if(val <= 28){
    vw_send((uint8_t *)motorOn, strlen(motorOn));
    vw_wait_tx();          
    Serial.println(val);
  }
  else if(val <= 55){
    vw_send((uint8_t *)motorOn1, strlen(motorOn1));
    vw_wait_tx();          
    Serial.println(val);
  }
  else if(val <= 100){
    vw_send((uint8_t *)motorOn2, strlen(motorOn2));
    vw_wait_tx();          
    Serial.println(val);
  }
  else if(val <= 150){
    vw_send((uint8_t *)motorOn3, strlen(motorOn3));
    vw_wait_tx();          
    Serial.println(val);
  } 
  else if(val <= 200){
    vw_send((uint8_t *)motorOn4, strlen(motorOn4));
    vw_wait_tx();          
    Serial.println(val);
  }
  else if(val <= 255){
    vw_send((uint8_t *)motorOn5, strlen(motorOn5));
    vw_wait_tx();          
    Serial.println(val);
  }
}

 

and this for the receiver :

// RECEIVER CODE

#include <VirtualWire.h>

int motorPin = 3;

void setup()
{
  pinMode(motorPin, OUTPUT);
  Serial.begin(9600);
 
  while (! Serial);
  Serial.println("Speed 0 to 255");
 
  vw_setup(2000);
  vw_set_rx_pin(3);
  vw_rx_start();
}
void loop()
{
  uint8_t buflen = VW_MAX_MESSAGE_LEN;
  uint8_t buf[buflen];
 
  if(vw_get_message(buf, &buflen))
  {
    //int val = map(analogRead(potPin), 0, 1023, 0, 255);

   
    for(int i = 0; i < buflen; i++)
    {
      if(buf[i] == 'a')
      {
         analogWrite(motorPin, 28);
      }
      else if(buf[i] == 'b')
      {
         analogWrite(motorPin, 55);
      }
      else if(buf[i] == 'c')
      {
         analogWrite(motorPin, 100);
      }
      else if(buf[i] == 'd')
      {
         analogWrite(motorPin, 150);
      }
      else if(buf[i] == '4')
      {
         analogWrite(motorPin, 200);
      }
      else if(buf[i] == '5')
      {
         analogWrite(motorPin, 255);
      }
    }
  }
 
 
}

Just a quick glance

Please understand, I did not spend much time looking this over --There could easily be more issues that what I am seeing here. That said, here are the highlights:

You are using a series of if <='s in your transmit code. Let’s say the value we are working with is 28. Every one of your If statements would be true and all of them are going to be executed.

On the receive side, you for some reason go from “a”, “b”, “c”, “d”, to “4”, “5”. --I would bet this is not correct.

I see you are writing a PWM value to one single output pin, --if you are using a motor driver chip, what are you doing with the extra control pins?

 

actully no i am not using a

(I added the schematics pictures)

actully no i am not using a chip, just a transister and potentiometer

then about programming RF links i understand some stuff on how to do it but still confused with the conversion of signal thing and what does the transmitter send and what does the receiver really get ?!

all i need to do is being able to control the DC motor speed with a potentiometer via RF links !! that’s my object here

The ASCII chart

If you are sending stuff via serial, sooner or later you are going to have to deal with the ASCII chart…

Do a search for ASCII Chart, print one out and tape it to your wall. It will show you all the different forms your numbers can be in.

yes i have it, but i know

yes i have it, but i know that i should use it just when i am sending variables from the keyboard isn’t it ?

and i need please to know something :

when i am taking variables from the A0 which has the potentiometer connected to it, and then sending this via the transmitter so how does the transmitter send these variables in which form ? and how does the receiver receives it ?

I don’t know

I really don’t know how the data is being sent “behind the scenes”. I mean, I am not sure of the specific operation of this library. 

I would try this:

Get your transmitting Arduino to send out a simple count, 1,2,3,4…  Send them as bytes, one a second. Have your RX arduino receive these values and send them to your serial monitor. See what comes through. 

I would also try the Arduino Cast function as well. http://www.arduino.cc/en/Reference/Cast

 

I wish I could explain this better, but really, the best thing to do here is to simply play with it. Forget about your motor and pot, just send a simple 0-255 count, and try to catch it on the other side. Play with converting before you send, after you receive, etc.  Keep an eye on that ASCII chart (especially when using the Serial Monitor) and simply keep track of your findings as you go.

You will get this guy figured out.

ok i will try to understand

ok i will try to understand what to send to make the conversion from potentiometer to the other arduino

yes i corrected the drawing,

yes i corrected the drawing, the problem is just in this drawing not in my real circuit

Why are we connecting these things…

Ok guys, I think I can start to see the issue here…

Firashelou, I think you are (and have been) looking for a tutorial that tells you step-by-step how to connect everything and what code to run. When I say “step-by-step” I mean, I think you are looking for a very specific tutorial, using EXACTLY the parts you have, using the EXACT set up you have. When you have been able to “make it look like the picture” you can get it to work, however, when we add any deviations, we run into problems. As an example, I note your 4-pin unit and the 8-pin unit I linked to…  You seemed very confused (and did not want to follow the tutorial) when in reality, the units were almost identical with the pins simply being repeated twice (two grounds, two VCC’s etc). --This leads me to think you can/ have followed tutorials in the past, but only by matching what they are doing --not knowing why these things are connected this way.

I could not help but notice this seems to be the case with your Fritzing… The guys are arguing that the pinout is not correct, you say you matched a tutorial exactly, and then we start talking model numbers of specific parts.  --This is what I am talking about. The transmitter does not work because it got plugged into the breadboard a certain way --it works because it has power, gnd, signal and antenna. Almost 1/2 this thread is about pinouts and devices and its for a simple reason --we are all here at step 47, but skipped steps 1-10. 

 

Here’s what you do:
Forget about the motor, forget about the tutorials, turn off the youtube. Disconnect every wire you have everywhere. Now, grab only the TX unit. Hold it in your hand and see if there are any markings near the pins. Are there? If so, write them down. Now, find the specific datasheet for your specific model (specifically from where you bought it) and find the page with the pinouts. Confirm that what is written on the device (if any) matches what is in the manual. Now double check it. Now, in your notebook, draw a little picture of your TX unit, draw the pins, and lable them in the drawing. Draw it clearly so you can not get confused as to which side of the device you are looking at. You may even want to grab a marker and put a dot over pin 1. Take your time, be sure you are correct before you draw that picture in your notebook. ***Nothing goes in the notebook that you are not 100% sure about. 

Repeat the above with the RX unit. Take your time, use the same amount of care. Put everything in your notebook. 

You should not need a tutorial for any of the above, just the 2 units and datasheet(s).

Once you are 100% sure you have the pinouts correct, plug each unit into its breadboard. Connect nothing else. Go back to your datasheet and confirm the VCC requirements of the units (are they 3.3v or 5v units?). Once you have determined the power required, connect only GND (ground) and VCC (3.3v/5v) to each unit. At this point, you may also connect the short piece of wire needed for the antenna. Do not connect anything else.

At this point, we can be fairly sure we have everything connected correctly. --Not because we matched what a youtube video “looked like” but because we checked datasheets, checked pinouts, and knew why we were connecting what-to-what. I should also note that we do NOT have a motor connected right now. --The reason is, we have no idea if the motor’s connections work or not. We have not tested the motor by itself, we can not trust it as a “indicator” at all, we should not use it for testing.

If we look at our notebook and out breadboards, we will notice we probably have 2 connections left, one on each unit --TX/RX. The TX will have to come from an output of one arduino, the RX to the input of another. At this point, we don’t look at the youtube or the tutorial to find where they go, we look to the code. It usually does not matter what goes where, as long as the pin defined in the code, matches real life. Confirm your pin numbers and make your final two connections.

 

Now, at this point, I would actually use the tutorial (or at least its code). I would try to find the easiest, simplest sample code I could find and run it. Specifically, I would use the example included with your library. Do not modify it, and make note of any comments included in the header of the code. --If any weird connections are required, they are usually noted in the comments of the code example.

Run the example code. Confirm that it works. If it does, we now know one important thing: Your TX and RX units are wired correctly and work. Do not change or disconnect anything from here-on-out. This is now a constant. As we move on and you change things (and it stops working) we will now know the problem is the thing you added or changed, we can trust the basic set-up (we tested it individualy).

From here, I suggest going back to the ASCII stuff, and more importantly, sending that 1,2,3, count. Have the TX send a simple count 0-255, once a second. Try to catch this on the RX end. Play with different formats --defining the variable to be sent as a byte, char, str, etc. Read any info you can find about the library and how things get sent. Same thing with the receiver --do you need to convert variable types as they come in? --Play with this, play with this, play with this. --Don’t follow tutorials, do this like a scientist --one thing changed at a time, run it, note the results. Read the Arduino website about data types, hit the arduino playground for info about the TX units, read info about the library. In the end, be able to send a 27 and get a 27 --or be able to send an “A” and get an “A”. 

Now, take all of the above and forget about it. Grab only your pot. Use the basic arduino example (in the IDE) to read your pot and send the numbers to the serial monitor. Test the pot by itself. You should be getting close to a 0-1023 range in the serial monitor. Convert this number to a byte using the Map function or by simply dividing by 4. Repeat the test above and confirm that you are now getting numbers (from the pot and ADC input) of 0-255 in the serial monitor.

Now, go back to the code you use for the “counting” test (remember, we tested it by itself and we know it works). Remove the counting bit, and instead add the code needed to read your pot and convert to 0-255. I would leave in the 1 second delay however. Now re-run this code. Does this code work just like the counting code? Does the number change on the RX end as you turn the pot on the TX end? --I would be it does work… We tested each part by itself! –If this does not work, you should have no problem finding out why --you tested each part by themselves, you know how they work.

At this point, you can move on to your motor. Test it by itself. Build the little circuit, and connect the final “control wire” (going to the base of the transistor) to the PWM output pin of your Arduino. Write some code to play with the analogWrite command and be sure your motor works and you can control its speed. 

And that’s it. --You can now read a pot, send a number, control PWM via analogWrite --and you know each one works by itself. Just put them together now.

 

 

 

.

.

well not everything i don’t

well not everything i don’t know about, i am still a beginner yes, but i know for example about the pins thing but off course some stuff are knew to me, i made a control of a DC motor by a potentiometer and it works fine and i added a throttle like the one used for rc helicopter and it works great, but my problem is in the code thing because i about the RF i know how and when to connect every pin but in fact the model i have does not have any datasheet or i couldn’t find any on google !! but i used the sparkFun one it’s close to it

but thanks a lot about your advices i really appreciate it it’s really helpfull for the process of learning and really progress in this hobby, i will do exactly as you said once again to make sure i printed it in my head for the future, i will go step by step and i hope everything will be on the right track :slight_smile:

by the way the count thing in the codes i still didn’t get it !! why do we use it ? what does it count and from where ?!

hey Chris i did everything

hey Chris

i did everything you told me and everything worked fine and i understood most of the events and codes that happened . After that i decided to get everything together and try to control the DC motor with a potentiometer by the RF links

so i wrote my codes step by step, i am sure not everything is correct especially with the data conversion so the dc motor runs even if my value from the potentiometer is 0 and then stop for a bit and then runs again and same if the value change till 255 (i guess same issue that happened in the other post and it’s because the breadboard but how can i know if the dc motor is running as i want it to ?! to be controlled i mean ?!! i didn’t use transistor so i guess this is another issue ?) so here are my codes i will comment the lines which i guess are not true or not clear :

//TRANSMITTER

#include <VirtualWire.h>

int potPin = A0;
int transmitPin = 3;

void setup(){
  Serial.begin(9600);
  vw_setup(2400);     //set the speed
  vw_set_tx_pin(transmitPin);   //set the transmit pin
}

void loop(){
    int val = analogRead(potPin);
    val = map(val, 0, 1023, 255, 0);
    char c = val;                      // i mapped it and then stored it into val which is stored in character c (donno if this method is right) ?
   
    if(c <= 255)           // i donno if i can put a 255 without single quotes ?! same for 0

    {
      vw_send((uint8_t *)c, 3);
    }
    else if(c == 0)          
    {
      vw_send((uint8_t *)c, 1);
    }
    Serial.print(val);  // i got values on the monitor
    Serial.println(" current");
    delay(1000);
 
}

 

//RECEIVER

#include <VirtualWire.h>

int receivePin = A0;

void setup()
{
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
 
  vw_setup(2400);
  vw_set_rx_pin(receivePin);
  vw_rx_start();
}

void loop()
{
  uint8_t buflen = VW_MAX_MESSAGE_LEN;
  uint8_t buf[buflen];
 
  if(vw_get_message(buf, &buflen)) 
  {
    for(int i = 0; i < buflen; i++)
    {
      if(buf[i] <= 255)  // i am not sure i guess this is wrong !! can i check the value this way from the array buf ?
      {
        digitalWrite(13, buf[i]);     //i tried here the analogWrite and i got a less signal for the motor and it runs with a less speed :smiley:
        Serial.print(buf[i]);     // i didn’t get anything on the monitor !!
        Serial.println(" current");
        delay(1000);
      }
      else if(buf[i] == 0)
      {
        digitalWrite(13, LOW);
        Serial.print(buf[i]);        
        Serial.println(" current");
        delay(1000);
      }
    }
  }

}

One quick one

I can assume you have your motor conected to pin 13. Pin13 is not a PWM output, it can do “speed control” (analogWrite). Try your code above again, but with a PWM output pin and let me know.

i even tried with pin 3

i even tried with pin 3 which was my last testing before clicking post but still it gave me the same results when i just connect the dc motor without any transistor

what’s happening is this : i plugged the motor in pin 3 PWM and i turned the pot to 0 and i changed in the receiver code digitalWrite to analogWrite so the dc motor start working even if pot value is 0 at a low speed  for a while !! (don’t know why !!) once it goes up once it stoped once it runs on low speed once on high !!

but when i change the value for pot it still the same speed , then it stoped (this one is from the breadboard for sure) but what i need to know is this part if it’s right ?!! (i commented the part which i am not sure about )

I guess it’s getting the signal the receiver i mean but in a very slow way !! it’s not responding fast for the change !!

  if(vw_get_message(buf, &buflen)) //buf is an array containing the message and buflen is the length or the message
  {
    for(int i = 0; i < buflen; i++)
    {
      if(buf[i] <= 255)  /////is this line right ? am i getting the value the way it should ?
      {
        analogWrite(3, buf[i]);  ///////// is this analogWrite() correct ? or i should put digitalWrite ??
        Serial.print(buf[i]);
        Serial.println(" current");
        delay(1000);
      }
     /* else if(buf[i] == 0)
      {
        digitalWrite(3, LOW);
        Serial.print(buf[i]);   /////how can i take the value which i am receiving and printed it on monitor ?
        Serial.println(" current");
        delay(1000);
      }*/
    }
  }

STOP STOP!!

Do NOT connect your motor directly to your Arduino! You may have already fried that output or possibly the whole chip.

Ok, gimme a second to see if I can go through your last post. I will respond soon.

Got it.

Is every change you are making taking about 1 second to happen? If so, it is because you still have a “delay(1000)” in there. This means, every time you are receiving something, it will wait and do nothing for one second.

The reason we use these delays is for debugging only. --It is so we can physically see the numbers via the serial monitor. If we didn’t use a delay, they would scroll by too fast to see. Once we confirm that we are “seeing the numbers we want” via the serial monitor, we normally comment-out the Serial commands, and remove the delays.

exactly i thought the same

exactly i thought the same but i guess it’s not !! but i need to know how to print the values which i am getting on receiver to see it on the monitor ?

and the motor is connected to breadboard and then to arduino !! do i have to put a resistor or capacitor or something ?

no no actully these codes

no no actully these codes are old lol

the new ones are :

//TRANSMITTER

#include <VirtualWire.h>

int potPin = A0;
int transmitPin = 3;

void setup(){
  Serial.begin(9600);
  vw_setup(2400);     //set the speed
  vw_set_tx_pin(transmitPin);   //set the transmit pin
}

void loop(){
    int val = analogRead(potPin);
    val = map(val, 0, 1023, 255, 0);
    char c = val;                      // i mapped it and then stored it into val which is stored in character c (donno if this method is right) ?
   
    if(c <= 255)           // i donno if i can put a 255 without single quotes ?! same for 0

    {
      vw_send((uint8_t *)c, 3);
    }
    else if(c == 0)          
    {
      vw_send((uint8_t *)c, 1);
    }
    Serial.print(val);  // i got values on the monitor
    Serial.println(" current");
    delay(1000);
 
}

 

//RECEIVER

#include <VirtualWire.h>

int receivePin = A0;

void setup()
{
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
 
  vw_setup(2400);
  vw_set_rx_pin(receivePin);
  vw_rx_start();
}

void loop()
{
  uint8_t buflen = VW_MAX_MESSAGE_LEN;
  uint8_t buf[buflen];
 
  if(vw_get_message(buf, &buflen)) 
  {
    for(int i = 0; i < buflen; i++)
    {
      if(buf[i] <= 255)  // i am not sure i guess this is wrong !! can i check the value this way from the array buf ?
      {
        digitalWrite(13, buf[i]);     //i tried here the analogWrite and i got a less signal for the motor and it runs with a less speed :smiley:
        Serial.print(buf[i]);     // i didn’t get anything on the monitor !!
        Serial.println(" current");
        delay(1000);
      }
      else if(buf[i] == 0)
      {
        digitalWrite(13, LOW);
        Serial.print(buf[i]);        
        Serial.println(" current");
        delay(1000);
      }
    }
  }

}

ok there something great

ok there something great here : i managed to make the motor turn on and off when i turn the pot from 0 to 255 or something between (when i open the monitor it works fine sometimes it gets stuck on 118 and motor always on even if i change the value of pot so i close it and run it again the monitor and it works) by writing digitalWrite(3, buf[i]) :

if(buf[i] <= 255)
 {
        digitalWrite(3, buf[i]);
        Serial.print(buf[i]);
        Serial.println(" current");
        //delay(5000);
}

but my target is to make its speed goes up and down depending to the pot value so do i have to write analogWrite() instead of digitalWrite() ? or the problem here is buf[i] ?? the main problem now is how to convert to analog signal !! :S

ok i guess i found now what

ok i guess i found now what the problem is but i am not being able to correct it :

i guess as i understood before that the array buf[] is storing the converted values of potentiometer so a for(){} loop must be added or something similar to make the program goes into every value of buf[] and give the motor the current in parallel to pot (donno if this is right but from trying and adding that’s what i found it is because when the program runs it is taking a specific value and run the motor according to that value in this moment it’s a low speed but if i unplug the pin from 3 and plugged it again and change the value of pot it takes a different speed and continu with it with none stop even if pot is 0) here are the new codes for receiver :

#include <VirtualWire.h>

int receivePin = A0;

void setup()
{
  pinMode(3, OUTPUT);
  //digitalWrite(3, LOW);
 
  vw_setup(2400);
  vw_set_rx_pin(receivePin);
  vw_rx_start();
}

void loop()
{
  uint8_t buflen = VW_MAX_MESSAGE_LEN;
  uint8_t buf[buflen];
 
  if(vw_get_message(buf, &buflen)) //buf is an array containing the message and buflen is the length or the message
  {
    for(int i = 0; i < buflen; i++)
    {
      if(buf[i]  >= 0 && buf[i] <= 255)
      {
        for( i = 0; i < buflen; i++)
        {
          analogWrite(3, buf[i]);
          Serial.print(buf[i]);
          Serial.println(" current");
        }
        //delay(5000);
      }
     /* else if(buf[i] == 0)
      {
        analogWrite(3, LOW);
        Serial.print(buf[i]);
        Serial.println(" current");
        delay(1000);
      }*/
    }
  }

}