请原谅我这个问题的冗长性,但这超出了我的专业知识,我不知道该去哪里。
我正在尝试通过教练电缆将PPM信号发送到FlySkyi10无线电。当使用下面的PPM代码时,我可以将正确的PPM信号发送到我的收音机。
//this programm will put out a PPM signal
//////////////////////CONFIGURATION///////////////////////////////
#define chanel_number 8 //set the number of chanels
#define default_servo_value 1500 //set the default servo value
#define PPM_FrLen 22500 //set the PPM frame length in microseconds (1ms = 1000µs)
#define PPM_PulseLen 300 //set the pulse length
#define onState 1 //set polarity of the pulses: 1 is positive, 0 is negative
#define sigPin 10 //set PPM signal output pin on the arduino
//////////////////////////////////////////////////////////////////
/*this array holds the servo values for the ppm signal
change theese values in your code (usually servo values move between 1000 and 2000)*/
int ppm[chanel_number];
void setup(){
//initiallize default ppm values
for(int i=0; i<chanel_number; i++){
ppm[i]= default_servo_value;
}
pinMode(sigPin, OUTPUT);
digitalWrite(sigPin, !onState); //set the PPM signal pin to the default state (off)
cli();
TCCR1A = 0; // set entire TCCR1 register to 0
TCCR1B = 0;
OCR1A = 100; // compare match register, change this
TCCR1B |= (1 << WGM12); // turn on CTC mode
TCCR1B |= (1 << CS11); // 8 prescaler: 0,5 microseconds at 16mhz
TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
sei();
}
void loop(){
//put main code here
static int val = 1;
ppm[0] = ppm[0] + val;
if(ppm[0] >= 2000){ val = -1; }
if(ppm[0] <= 1000){ val = 1; }
delay(10);
}
ISR(TIMER1_COMPA_vect){ //leave this alone
static boolean state = true;
TCNT1 = 0;
if(state) { //start pulse
digitalWrite(sigPin, onState);
OCR1A = PPM_PulseLen * 2;
state = false;
}
else{ //end pulse and calculate when to start the next pulse
static byte cur_chan_numb;
static unsigned int calc_rest;
digitalWrite(sigPin, !onState);
state = true;
if(cur_chan_numb >= chanel_number){
cur_chan_numb = 0;
calc_rest = calc_rest + PPM_PulseLen;//
OCR1A = (PPM_FrLen - calc_rest) * 2;
calc_rest = 0;
}
else{
OCR1A = (ppm[cur_chan_numb] - PPM_PulseLen) * 2;
calc_rest = calc_rest + ppm[cur_chan_numb];
cur_chan_numb++;
}
}
}
但是,当我通过i2c和其他一些功能从传感器读取数据时,就会出现问题。一旦使用i2c代码,PPM信号就会变得嘈杂,应该是1500ms的信号却具有+/- 20ms的噪声。
我不想让这篇文章太笨重,我已经将LSM9DS0的i2c库用于读取传感器数据。我没有在任何地方使用中断,因此我将不得不仔细看一下库。不幸的是,我对此并不了解。下面是从seesors中读取的简化代码。图书馆的网站在这里:https://learn.adafruit.com/adafruit-lsm9ds0-accelerometer-gyro-magnetometer-9-dof-breakouts/arduino-code
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_LSM9DS0.h>
#include <Adafruit_Sensor.h> // not used in this demo but required!
// i2c
Adafruit_LSM9DS0 lsm = Adafruit_LSM9DS0();
// You can also use software SPI
//Adafruit_LSM9DS0 lsm = Adafruit_LSM9DS0(13, 12, 11, 10, 9);
// Or hardware SPI! In this case, only CS pins are passed in
//Adafruit_LSM9DS0 lsm = Adafruit_LSM9DS0(10, 9);
void setupSensor()
{
// 1.) Set the accelerometer range
lsm.setupAccel(lsm.LSM9DS0_ACCELRANGE_2G);
//lsm.setupAccel(lsm.LSM9DS0_ACCELRANGE_4G);
//lsm.setupAccel(lsm.LSM9DS0_ACCELRANGE_6G);
//lsm.setupAccel(lsm.LSM9DS0_ACCELRANGE_8G);
//lsm.setupAccel(lsm.LSM9DS0_ACCELRANGE_16G);
// 2.) Set the magnetometer sensitivity
lsm.setupMag(lsm.LSM9DS0_MAGGAIN_2GAUSS);
//lsm.setupMag(lsm.LSM9DS0_MAGGAIN_4GAUSS);
//lsm.setupMag(lsm.LSM9DS0_MAGGAIN_8GAUSS);
//lsm.setupMag(lsm.LSM9DS0_MAGGAIN_12GAUSS);
// 3.) Setup the gyroscope
lsm.setupGyro(lsm.LSM9DS0_GYROSCALE_245DPS);
//lsm.setupGyro(lsm.LSM9DS0_GYROSCALE_500DPS);
//lsm.setupGyro(lsm.LSM9DS0_GYROSCALE_2000DPS);
}
void setup()
{
#ifndef ESP8266
while (!Serial); // will pause Zero, Leonardo, etc until serial console opens
#endif
Serial.begin(9600);
Serial.println("LSM raw read demo");
// Try to initialise and warn if we couldn't detect the chip
if (!lsm.begin())
{
Serial.println("Oops ... unable to initialize the LSM9DS0. Check your wiring!");
while (1);
}
Serial.println("Found LSM9DS0 9DOF");
Serial.println("");
Serial.println("");
}
void loop(void)
{
/* Get a new sensor event */
sensors_event_t accel, mag, gyro, temp;
lsm.getEvent(&accel, &mag, &gyro, &temp);
// print out accelleration data
Serial.print("Accel X: "); Serial.print(accel.acceleration.x); Serial.print(" ");
Serial.print(" \tY: "); Serial.print(accel.acceleration.y); Serial.print(" ");
Serial.print(" \tZ: "); Serial.print(accel.acceleration.z); Serial.println(" \tm/s^2");
// print out magnetometer data
Serial.print("Magn. X: "); Serial.print(mag.magnetic.x); Serial.print(" ");
Serial.print(" \tY: "); Serial.print(mag.magnetic.y); Serial.print(" ");
Serial.print(" \tZ: "); Serial.print(mag.magnetic.z); Serial.println(" \tgauss");
// print out gyroscopic data
Serial.print("Gyro X: "); Serial.print(gyro.gyro.x); Serial.print(" ");
Serial.print(" \tY: "); Serial.print(gyro.gyro.y); Serial.print(" ");
Serial.print(" \tZ: "); Serial.print(gyro.gyro.z); Serial.println(" \tdps");
// print out temperature data
Serial.print("Temp: "); Serial.print(temp.temperature); Serial.println(" *C");
Serial.println("**********************\n");
delay(250);
}
有人有建议吗?
答案 0 :(得分:0)
我将从传感器读取数据的方法更改为SPI,从而解决了该问题。 ppm信号中的所有噪声均已消除。