Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
11 years ago.
Combination of Serial & SPI Communication & PWMin
Hi, i have a problem in my thesis about visual tracking Navigation - UAV octorotor. i'm trying to combine serial communication, SPI, and PWMin (5 chanel PWMin became PPM) in mbed LPC4088. I use serial interrupt in my serial communication, i use InterruptIn in SPI, and i use PWMin.h in mbed library. But, everytime i try to run this 3 communication, the data that is received from R/C is not stable. Is there anyone know about the solution of this problem? Strangely enough, when I try not to combine them and run them separately, the communication runs well.
This is my code :
include the mbed library with this snippet
PwmIn Ch1(p16); PwmIn Ch2(p17); PwmIn Ch3(p18); PwmIn Ch4(p15); PwmIn Ch6(p33); SPISlave device(p11, p12, p13, p14); // mosi, miso, sclk, ssel InterruptIn event(p9); void ON_PPM(int param){ t.start(); while (t.read_us() <= param) { SignalPPM = 1; } t.stop(); t.reset(); } void OFF_PPM(){ t.start(); while (t.read_us() <= mean_idle_time) { SignalPPM = 0; } t.stop(); t.reset(); } void Manual(){ LED_visual = 0; LED_manual = 1; LED_waypoint = 0; OFF_PPM(); ON_PPM(chanel_1); OFF_PPM(); ON_PPM(chanel_2); OFF_PPM(); ON_PPM(chanel_3); OFF_PPM(); ON_PPM(chanel_4); OFF_PPM(); ON_PPM(chanel_5); OFF_PPM(); ON_PPM(chanel_6); OFF_PPM(); ON_PPM(chanel_7); OFF_PPM(); ON_PPM(chanel_8); OFF_PPM(); ON_PPM(chanel_9); OFF_PPM(); ON_PPM(chanel_10); OFF_PPM(); ON_PPM(chanel_11); OFF_PPM(); ON_PPM(chanel_12); OFF_PPM(); ON_PPM(12000); } /* void Impulse(int waktu){ int x; t.start(); x = t.read_us(); while (abs(x - t.read_us()) <= waktu){ chanel_out_roll = 1000 + (int) temp2_chanel_roll; chanel_out_pitch = 1000 + (int) temp2_chanel_pitch; } chanel_out_roll = 1000; chanel_out_pitch = 1000; t.stop(); t.reset(); } */ void Visual(){ controller(); chanel_out_yaw = (int) temp_chanel_yaw; //Impulse(50000); chanel_out_roll = 1000 + (int) temp2_chanel_roll; chanel_out_pitch = 1000 + (int) temp2_chanel_pitch; LED_visual = 1; LED_manual = 0; LED_waypoint = 0; OFF_PPM(); ON_PPM(chanel_1); OFF_PPM(); ON_PPM(chanel_out_yaw); OFF_PPM(); ON_PPM(chanel_out_pitch); OFF_PPM(); ON_PPM(chanel_out_roll); OFF_PPM(); ON_PPM(1000); OFF_PPM(); ON_PPM(chanel_6); OFF_PPM(); ON_PPM(1000); OFF_PPM(); ON_PPM(1000); OFF_PPM(); ON_PPM(1000); OFF_PPM(); ON_PPM(1000); OFF_PPM(); ON_PPM(1000); OFF_PPM(); ON_PPM(1000); OFF_PPM(); ON_PPM(12000); } void Waypoint(){ LED_visual = 0; LED_manual = 0; LED_waypoint = 1; OFF_PPM(); ON_PPM(chanel_1); OFF_PPM(); ON_PPM(chanel_2); OFF_PPM(); ON_PPM(chanel_3); OFF_PPM(); ON_PPM(chanel_4); OFF_PPM(); ON_PPM(chanel_5); OFF_PPM(); ON_PPM(chanel_6); OFF_PPM(); ON_PPM(chanel_7); OFF_PPM(); ON_PPM(chanel_8); OFF_PPM(); ON_PPM(chanel_9); OFF_PPM(); ON_PPM(chanel_10); OFF_PPM(); ON_PPM(chanel_11); OFF_PPM(); ON_PPM(chanel_12); OFF_PPM(); ON_PPM(12000); } void Build_PPM(){ temp_chanel_1 = Ch2.pulsewidth()*1000000; chanel_1 = temp_chanel_1 - mean_idle_time; temp_chanel_2 = Ch3.pulsewidth()*1000000; chanel_2 = temp_chanel_2 - mean_idle_time; temp_chanel_3 = Ch1.pulsewidth()*1000000; chanel_3 = temp_chanel_3 - mean_idle_time; temp_chanel_4 = Ch4.pulsewidth()*1000000; chanel_4 = temp_chanel_4 - mean_idle_time; temp_chanel_5 = 1500; chanel_5 = temp_chanel_5 - mean_idle_time; temp_chanel_6 = Ch6.pulsewidth()*1000000; chanel_6 = temp_chanel_6 - mean_idle_time; temp_chanel_7 = 1500; chanel_7 = temp_chanel_7 - mean_idle_time; temp_chanel_8 = 1500; chanel_8 = temp_chanel_8 - mean_idle_time; temp_chanel_9 = 1500; chanel_9 = temp_chanel_9 - mean_idle_time; temp_chanel_10 = 1500; chanel_10 = temp_chanel_10 - mean_idle_time; temp_chanel_11 = 1500; chanel_11 = temp_chanel_11 - mean_idle_time; temp_chanel_12 = 1500; chanel_12 = temp_chanel_12 - mean_idle_time; if (temp_chanel_6 <= 1300) { Manual(); } else if (temp_chanel_6 >1300 && temp_chanel_6 <= 1650) { Visual(); } else { Waypoint(); } } void Serial_Configuration(void) { pc.baud(9600); //Baudrate di set sebesar 115200 bit per second pc.attach(&Rx_interrupt, Serial::RxIrq); //setting interrupt //Menerima default format yaitu 8 bits tanpa parity bit. } void Serial_StateMachine(void) { RxBuffer = pc.getc(); Serial_CurrentState = Serial_NextState; switch (Serial_CurrentState) { case Serial_Ready : { if (RxBuffer ==ID_X) { pc.printf ("ID_X = "); Serial_NextState = Serial_Receive_X; index = 0; } else if (RxBuffer == ID_Y) { pc.printf ("ID_Y = "); Serial_NextState = Serial_Receive_Y; index = 0; } break; } case Serial_Receive_X : { if (index<3) { data_x[index] = RxBuffer - 48 ; index++; if (index == 3) { temp_position_pixel_x = (100*data_x[0] + 10*data_x[1] + data_x[2]); if (temp_position_pixel_x <=320) { position_pixel_x = temp_position_pixel_x; lebih_x = temp_position_pixel_x; } else { lebih_x = temp_position_pixel_x; } pc.printf ("%d", position_pixel_x ); Serial_NextState = Serial_Ready; Serial_datastate_x = NEW; } } break; } case Serial_Receive_Y : { if (index<3) { data_y[index] = RxBuffer - 48 ; index++; if (index == 3) { temp_position_pixel_y = (100*data_y[0] + 10*data_y[1] + data_y[2]); if (temp_position_pixel_y <=240) { position_pixel_y = temp_position_pixel_y; lebih_y = temp_position_pixel_y; } else { lebih_y = temp_position_pixel_y; } pc.printf ("%d \n ", position_pixel_y ); Serial_NextState = Serial_Ready; Serial_datastate_y = NEW; } } break; } default: break; } } void receive_union(){ indexx = 0; validasi = 0; device.frequency(10000000); while(indexx < 8 && validasi != 1) { if(device.receive()) { led2 = !led2; Rx2Buffer = device.read(); Rx2Buffer&=0x7F; SPI_CurrentState = SPI_NextState; switch(SPI_CurrentState){ case SYNC_SPI: { if (Rx2Buffer == '#') { SPI_NextState = DATA; } else { SPI_NextState = SYNC_SPI; } break; } case DATA: { int_value[indexx] = Rx2Buffer; pc.printf("%c",int_value[indexx]); indexx++; if ((indexx>7) || (Rx2Buffer == '*')){ indexx=0; validasi = 1; SPI_NextState = SYNC_SPI; } break; } default : break; } } } } int main() { event.rise(&receive_union); //p9 Serial_Configuration(); //74 us while (1) { Build_PPM(); } }
1 Answer
11 years ago.
The RC data you receive is using interrupts I assume? (PwmIn is interrupt driven IIRC). Then it is simply a case that the processing of the RC interrupt is delayed by other interrupts. So check out how long those take to handle, and either optimize them, don't handle them as interrupt but in your while(1) loop, or give them lower priority than other interrupts. (Although for your InterruptIn thats not possible since that uses the same handler as PwmIn).
Btw your ON and OFF functions just are wait functions, easier to use that than a timer.
Thx Erik. But, i handled RC in while(1) loop => build PPM(). Can u give me some example to optimize those interrupt? and how to change the interrupsts priority?
posted by 04 Sep 2014Interrupt priority can't be lower than your main loop, so if thats your issue that won't fix it (outside of disabling interrupts).
First of all you need to figure out however which part is going wrong. Is it that PwmIn gives you the wrong values, or that those are correct but your build PPM function gives the errors?
posted by 04 Sep 2014i use Pwmin in mbed library. When i run this program only with "Build PPM" in main loop, it's going well. So, my PPM code is going well, isn't it? what should i do? should i try use "enable_irq" and "disable_irq"? but how?
posted by 04 Sep 2014Well disable then when they need to be disabled and otherwise keep them enabled, but it might very well really hurt your PwmIn capabilities.
As I said, the first thing you need to figure out which part is going wrong, and how long each interrupt takes + how often they are called.
posted by 04 Sep 2014