Using VirtualWire with Timer Registers

Hello,

I am going to control two motors of my robot by using two of single-axis joysticks wirelessly. The transmitter works well, for it sends the analog reading of my joysticks to my receiver. I observed this by connecting the receiver with my arduino UNO board, and let the board do Serial.print the values on my computer screen.

Now, I am trying to convert the reading to be the value of timer registers OCR1A and OCR1B to let them drive my H-bridge circuits. But when I write a code containing “OCR1A” or “OCR1B”, the UNO just stops running for a while, and the receiver is out of connection. The UNO doesn’t do the Serial.print again. When I remove these two instructions, the UNO works fine.

How can I address this problem?

The code of my receiver is:

#include <VirtualWire.h>

void setup() {

pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
//Set Timer Register
ICR1 = 255;
TCCR1A =(1<<COM1B1)|(1<<COM1A1)|(1<<WGM11);
TCCR1B = (1<<WGM13)|(1<<WGM12)|(0<<CS12)|(1<<CS11)|(1<<CS10);
OCR1A = 0;
Serial.begin(9600);
vw_set_ptt_inverted(true); // Required for DR3100
vw_set_rx_pin(5);
vw_setup(4000); // Bits per sec
pinMode(13, OUTPUT);
vw_rx_start(); // Start the receiver PLL running

}

void loop() {
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
int xread = 0;
int yread = 0;
int switchread =1;

if (vw_get_message(buf, &buflen)) { // Non-blocking
vw_wait_rx_max(7000);
xread = (buf[0]-‘0’)*1000 + (buf[1]-‘0’)*100 + (buf[2]-‘0’)*10 + (buf[3]-‘0’)*1;
yread = (buf[5]-‘0’)*1000 + (buf[6]-‘0’)*100 + (buf[7]-‘0’)*10 + (buf[8]-‘0’)*1;
switchread = buf[10]-48;

//The pattern of messages sent is that buf[0] to buf[3] will be the analogReading of the first joystick ranging from 0 to 1023, and the buf[5] to buf[7] will be that of my second joystick. buf[10] will be the digitalReading of my switch and the rest are just headers to check the correctness of the information//

if (buf[4]==‘a’&&buf[9]==‘b’&&buf[11]==‘c’) {
Serial.print("A channel is ");
Serial.println(xread);
Serial.print("B channel is ");
Serial.println(yread);
Serial.print("SW status is “);
Serial.println(switchread);
Serial.println(” ");

OCR1A = 255xread/1023;
OCR1B = 255
yread/1023;

}//a b c check
else {
Serial.println(“ELSE”);
}
}//buf,buflen
else {
Serial.println(“Out of Connection”);
Serial.println(" ");
}

}

Thank you
BlackMelon

If the value that you send exceeds 128, multiplying by 255 will result in an overflow. That is not a good idea.

Why not do the math on the sending end, and just send the proper value, which will then only be three digits?

Don't you need to disable interrupts while diddling with the values of OCR1A and OCR1B?

If the value that you send exceeds 128, multiplying by 255 will result in an overflow

Oh! yes I agree with you. However, I used to replace the OCR1A = 255*xread/1023 with just "OCR1A = 0". At that time, the same problem occurred. (I wasn't do anything with OCR1B at that time). Anyway, I will try what you have suggested. :)

Don't you need to disable interrupts while diddling with the values of OCR1A and OCR1B?

How to do so? I want to know about this. I once used to program the UNO to drive an H-bridge circuit. At that time, I didn't disable interrupts. Everything just works fine.

Thank you very much

I don’t understand why you are diddling with the timer, anyway. How does that control an H-Bridge?

Why not drive the H-bridge the usual way, using PWM?

The timer is set to Fast PWM mode. OCR1A is a compare match register. At the beginning the PWM pin (atmega328's pin15) is high until the timer1, which is counting up, reaches OCR1A value. This will toggle the pin to low. So, the OCR1A defines the duty ratio.

This PWM signal will be sent to HIP4080A, an H-bridge driver IC, and there are other two pins of UNO to determine the direction of my motor. (The driver will compare these two pins, if one's voltage is higher than another, the motor will rotate clockwise and vice versa)

I just want to follow this. That's why I diddled with my timers. https://www.arduino.cc/en/Tutorial/SecretsOfArduinoPWM

"Why not drive the H-bridge the usual way, using PWM?"

What way do you mean? Do you mean setting the PWM pin high>delay>low>delay? I will do this if I can't solve this problem. But I want to practice some in-depth details of Atmega. In the future, I might use this to do things about high frequency inverters or dc-dc converters, so the accuracy of timing is of the essence.

Thanks

Update: I have just used the function "analogWrite" instead of timer registers. It has the same problem, showing "out of connection" for a while then stop doing Serial.print.

I added pinMode(9,OUTPUT);

and in the header checking condition, I added analogWrite(9,120);

VirtualWire uses Timer1, so you can't use that for PWM in a straightforward way.

VirtualWire uses Timer1, so you can't use that for PWM in a straightforward way.

Oh! Thank you! I didn't know that before. Seems that this is my worst nightmare because I might have to two atmega328s to control two motors since, in an atemega328, there are only three PWM pins, and two of them are controlled by Timer1.

Thanks again :)

Seems that this is my worst nightmare because I might have to two atmega328s to control two motors since, in an atemega328, there are only three PWM pins, and two of them are controlled by Timer1.

An AtMega328 has 6 PWM pins.

My worst nightmare is seemingly never ending: the presidential election in the U.S.

Just 8 more days, unless there are some recounts involved with Florida's hanging chad or similar elsewhere http://www.u-s-history.com/pages/h916.html like oversees absentee ballots being overlooked or declared invalid or ...

PaulS: An AtMega328 has 6 PWM pins.

Oh! Thank you very much! I thought that the AtMega328 would almost have the similar features as AtMega8. I have just rechecked that again, and I am glad that I was wrong. I can finish my project in a matter of days now. ^_^

jremington: My worst nightmare is seemingly never ending: the presidential election in the U.S.

CrossRoads: Just 8 more days, unless there are some recounts involved with Florida's hanging chad or similar elsewhere http://www.u-s-history.com/pages/h916.html like oversees absentee ballots being overlooked or declared invalid or ...

What do you want to see after the election? The Great Wall of America or Socialist Stuff?

One more thing about Arduino UNO, what kind of crystal on the board is it? A full-swing or low power crystal?