Hello,
I am currently building a MultiWii based drone, I have built the emisor-receptor that interface 4 analog signals(4 potentiometers to control the drone) and it works perfect, the receiver(arduino Nano, receives correctly the signal and parses it on 4 diferent integrers as expected (values between 1000 and 2000 because the MultiWii software expects that value range), but the problem is when I connect the receiver Nano to the MultiWii controller(Arduino UNO) the Arduino UNO receives incorrect values from the PPM signal(the four channels gets crazy unless the four potentiometers are turned full) so I think that the problem is the PPM generation process.
The problem is that I have taken code from internet to do that signal generation(because I don't know how to do it), and I don't know how to solve it.
Here I paste the NANO receiver to PPM code:
#define channel_number 4
#define sigPin 2
#define PPM_FrLen 27000
#define PPM_PulseLen 400
#include <SoftwareSerial.h>
int ppm[channel_number];
struct Received_data {
byte ch1;
byte ch2;
byte ch3;
byte ch4;
};
Received_data received_data;
String input;
int throttle, th;
int aileron, ail;
int elevator, el;
int rudder, rud;
unsigned long lastRecvTime = 0;
int boundLow;
int boundHigh;
const char delimiter = ',';
SoftwareSerial hc12(9, 10);
void setup()
{
Serial.begin(9600);
hc12.begin(9600);
pinMode(13, OUTPUT);
pinMode(sigPin, OUTPUT);
digitalWrite(sigPin, 0);
cli();
TCCR1A = 0;
TCCR1B = 0;
OCR1A = 100;
TCCR1B |= (1 << WGM12);
TCCR1B |= (1 << CS11);
TIMSK1 |= (1 << OCIE1A);
sei();
reset_received_Data();
}
void reset_received_Data()
{
received_data.ch1 = 0;
received_data.ch2 = 127;
received_data.ch3 = 127;
received_data.ch4 = 127;
PPM_width_Values();
}
void PPM_width_Values()
{
ppm[0] = map(received_data.ch1, 0, 255, 1000, 2000);
ppm[1] = map(received_data.ch2, 0, 255, 1000, 2000);
ppm[2] = map(received_data.ch3, 0, 255, 1000, 2000);
ppm[3] = map(received_data.ch4, 0, 255, 1000, 2000);
}
void receive_the_data()
{
if (hc12.available())
{
input = hc12.readStringUntil('\n');
if (input.length() > 0)
{
//Serial.println(input);
boundLow = input.indexOf(delimiter);
ppm[0] = input.substring(0, boundLow).toInt();
boundHigh = input.indexOf(delimiter, boundLow + 1);
ppm[1] = input.substring(boundLow + 1, boundHigh).toInt();
boundLow = input.indexOf(delimiter, boundHigh + 1);
ppm[2] = input.substring(boundHigh + 1, boundLow).toInt();
ppm[3] = input.substring(boundLow + 1).toInt();
Serial.print(ppm[0]); Serial.print(" ");
Serial.print(ppm[1]); Serial.print(" ");
Serial.print(ppm[2]); Serial.print(" ");
Serial.print(ppm[3]); Serial.print("\n");
delay(10);
}
}
}
void loop()
{
receive_the_data();
digitalWrite(13, HIGH);
}
#define clockMultiplier 2
ISR(TIMER1_COMPA_vect) {
static boolean state = true;
TCNT1 = 0;
if ( state ) {
//end pulse
PORTD = PORTD & ~B00000100;
OCR1A = PPM_PulseLen * clockMultiplier;
state = false;
}
else {
//start pulse
static byte cur_chan_numb;
static unsigned int calc_rest;
PORTD = PORTD | B00000100;
state = true;
if (cur_chan_numb >= channel_number) {
cur_chan_numb = 0;
calc_rest += PPM_PulseLen;
OCR1A = (PPM_FrLen - calc_rest) * clockMultiplier;
calc_rest = 0;
}
else {
OCR1A = (ppm[cur_chan_numb] - PPM_PulseLen) * clockMultiplier;
calc_rest += ppm[cur_chan_numb];
cur_chan_numb++;
}
}
}