Arduino and RC transmitter

I am new to Arduino and this forum, and this is my first Arduino project, besides tutorials.

I am trying to control a servo using an rc transmitter / receiver and Arudino. The reason I use Arduino instead of connecting the servo directly to the RC receiver is because the RC can only generate PWM from 1000 Hz to 2000 Hz, while I need PWM from 600 Hz to 2400 Hz to get the full range of motion of my servomotor, What I was trying to do was read the value from pulseIn () and then map this value from 0 to 180 degrees, as written in the code below (which uses the servo library).

However, with this code, the behavior of the engine is strange. When I move the control knob of the radio transmitter through its range of motion, the engine rotates from 0 to 45 degrees, back from 45 to 0, from 0 to 45 and returns to 0 again, and does not sweep from 0 to 180 degrees. Can anyone ask for help or advice?

Thank you very much

#include <Servo.h> Servo myservo; int ch1; int ch2; int ch3; int degree; void setup() { pinMode(7, INPUT); myservo.attach(9); Serial.begin(9600); } void loop() { ch3 = pulseIn(7, HIGH, 25000); degree = ((ch3-1250)* 180)/700; Serial.print("Channel 3:"); Serial.println(ch3); myservo.write(degree); delay(5); // waits 5ms for the servo to reach the position } 
+4
source share
2 answers

You overflow the int data type. The signed value can only be -32768 to +32767. See int docs

Your formula is all int , and the compiler will not guess that you might need a larger intermediate value. Multiplication by 180 is the red flag. (2000-1250) * 180 = 135000 = arrow

To understand the math, divide the formula into separate operations, as shown in the test program below. This is what the compiler does for you.

Run the program below and you will see a crash. Immediately after the out value reaches 45, the intermediate value overflows and the formula breaks.

 in: 1040 out: 39 t0: -210 t1: 27736 t2: 39 in: 1048 out: 41 t0: -202 t1: 29176 t2: 41 in: 1056 out: 43 t0: -194 t1: 30616 t2: 43 in: 1064 out: 45 t0: -186 t1: 32056 t2: 45 in: 1072 out: -45 t0: -178 t1: -32040 t2: -45 in: 1080 out: -43 t0: -170 t1: -30600 t2: -43 

Use this program below as a test fixture. Change the data types to use unsigned int, and you can draw the output as you need.

 int ch3; int degree; void setup() { ch3 = 1000; Serial.begin(9600); } void loop() { int t0, t1, t2; degree = ((ch3-1250)* 180)/700; t0 = ch3 - 1250; t1 = t0 * 180; t2 = t1 / 700; Serial.print("in: "); Serial.print(ch3); Serial.print(" out: "); Serial.print(degree); Serial.print(" t0: "); Serial.print(t0); Serial.print(" t1: "); Serial.print(t1); Serial.print(" t2: "); Serial.println(t2); ch3 += 8; if(ch3 > 2400) { ch3 = 1000; } delay(100); } 
+3
source

As a side note, you can have more Arduino / servo hits at https://robotics.stackexchange.com/ .

What do you see on the serial output? Is ch3 cyclic from 0 to 45 or from 0 to 180? Remember that map() designed to do what you do manually.

My first suspicion is that you sometimes come back from pulseIn because you turn off the time, or you start reading in the middle of a pulse (which can lead to a shorter pulse than you would expect).

0
source

All Articles