Hey everyone! I have made a program using Arduino Uno in building a ground test system for UAV fixed wings. That system measures :
- RPM (using optical sensor),
- voltage and current
- Load cell/force
First, I made program to control the bldc motor. I used ESC (electronic speed control) to control that motor. And it worked properly.
Second, I added sub-program to measure angular velocity of motor (in RPM). And it worked properly, the result was accurate compared to tachometer.
Third, I added sub-program to measure current (in closed loop system battery-bldc motor) and voltage of battery as a source. When I added this sub-program (compiled, uploaded to arduino and ran), the result of RPM measurement became not valid. When I deactivated current-voltage measurement sub-program and ran again, the result of RPM became valid again. Fyi, I was using interrupt function to calculate the rising edge pulse of optical sensor (in one rotation there were 2 rising edge, I was using 2 blade propeller). I gave a delay, so I got the amounts of rising edge in certain time interval. I got the number of time using millis() function in arduino.
RPM value can be calculated -> RPM= amounts rising edge in time interval *(1s/time interval in second)*30.
I presumed that the error RPM result appeared in the time interval as divider in equation above. When the content of my program just to calculate rpm, the RPM result was accurate because millis() fuction only calculated the time that was used in counting the amounts of rising edge. But, when the content of my program were RPM calculation and current-voltage measurement, the millis() function calculated the time that was used NOT ONLY in counting rising edge of the pulse, BUT ALSO included the time for processing current-voltage sub-program. So, I presumed that the error RPM result caused by time interval value as a divider in equation above. Is it right? How about you? If you have any solution, please let me know.
In addition, the value of voltage and current were error too when I put this sub-program in integrated program (control bldc, rpm measurement, current-voltage measurement in one file). But when I created new program in new file, just to calculate voltage and current, the result was accurate. I have tested, gave 2.5V as input voltage from power supply. In integrated program, the result was 2.1V, in new program (just to calculate current-voltage), the result was 2.5V (accurate). Do you have any solution?
Thank you very much. Glad to discuss with you for further.. ![]()
*this is my code, haven't included load cell sensor code
#include <Servo.h>
#define MAX_SIGNAL 2000
#define MIN_SIGNAL 1000
#define MOTOR_PIN 9
int speed;
int ds=1075;//desired speed
volatile long pulse_counter=0;
int pulse_counter_t=0;
int pulse_counter_tminus1=0;
int delta_pulse_counter=0;
long timer=0;
long old_timer;
long delta_timer;
float rpm;
Servo motor;
//function to calculate rising edge of pulse
void counter_pulse() {
pulse_counter=pulse_counter+1;
}
void setup() {
Serial.begin(9600);
Serial.println("Starting program");
Serial.println("Calibrate ESC");
motor.attach(MOTOR_PIN);
Serial.println("Give max input value");
Serial.println("Please connect the battery, wait a moment, press any key and enter");
motor.writeMicroseconds(MAX_SIGNAL);
// Wait for input
while (!Serial.available());
Serial.read();
delay(2000);
// Send min output
Serial.println("Give minimal input value");
motor.writeMicroseconds(MIN_SIGNAL);
Serial.println("Calibration is done!");
attachInterrupt(1, counter_pulse, RISING);//go to counter_pulse function when rising edge
}
void loop() {
//my ESC must be given incremental value to run the motor, from 1000 to 1075 ->5++
for(speed = 1000; speed <= 1100; speed += 5){
motor.writeMicroseconds(speed);
Serial.println(speed);
delay(100);
if(speed==ds){
for(speed=ds; speed<=ds; speed+=0){
motor.writeMicroseconds(ds);
if (Serial.available()>0){
ds = Serial.parseInt();
Serial.print("Input speed : "); Serial.println(ds);
}
Serial.print("Current input speed: ");Serial.println(ds);
//sub-program to calculate RPM
old_timer=timer;//initiate time(t-1)
timer=millis();//calculte time start from arduino ON
delta_timer=timer-old_timer;//calculate time interval
pulse_counter_tminus1=pulse_counter_t;//initiate amount of rising edge (t-1)
pulse_counter_t=pulse_counter;//initiate current amount of rising edge (t)
delta_pulse_counter=pulse_counter_t-pulse_counter_tminus1;//delta pulse
delay(1000);//give delay 1 s
rpm=30000*delta_pulse_counter/delta_timer;//calculate RPM
Serial.print("RPM : "); Serial.println(rpm);
//sub-program to calculate current-voltage
//analogRead arduino convert 0-5V input, scale to 0-1023.
float current=analogRead(A1);//read voltage in pin A1 (current sensor)
float dac_current=(arus/1023.0)*5;//scale 0-1023 to 0-5
float real_current=19.678339*dac_arus+0.1957492;//equation to calibrate sensor
float voltage=analogRead(A0);//read voltage in pin A0 (voltage sensor)
float dac_voltage=5.0/1023.0*tegangan;//scale 0-1023 to 0-5
float real_voltage=dac_tegangan*10;//eq to calibrate voltage sensor
Serial.print("Current: ");Serial.print(real_current);Serial.println("A");
Serial.print("Voltage: ");Serial.print(real_voltage);Serial.println("V");
}
}
}
}