cippy Postat Decembrie 14, 2014 Partajează Postat Decembrie 14, 2014 (editat) Salut, as dori sa stiu daca cele 2 coduri folosesc "timer interrupt" 1. #include <EEPROM.h>void setup() {noInterrupts(); pinMode(ppm, OUTPUT); pinMode(sw_mix, INPUT_PULLUP); // set to OUTPUT for scope trigger pinMode(sw_btn, INPUT_PULLUP); pinMode(sw_tog, INPUT_PULLUP);}void loop() {while (startup==1 && digitalRead(sw_btn) == 0) {// calibrate stickscalibrated=0;for (int stick=0; stick <4; ++stick) {raw=analogRead(stick);if (raw > stickcalHi[stick]) stickcalHi[stick] = raw;if (raw < stickcalLo[stick]) stickcalLo[stick] = raw;}}if (startup==1 && calibrated==0) {for (ch=0; ch<4; ch++) {EEPROMWriteInt(ch*4,stickcalLo[ch]); EEPROMWriteInt(ch*4+2,stickcalHi[ch]);}calibrated=1;}if (startup==1) {for (ch=0; ch<4; ch++) {stickcalLo[ch]=EEPROMReadInt(ch*4); stickcalHi[ch]=EEPROMReadInt(ch*4+2); reverse[ch]=EEPROM.read(ch+16) & 1; }reverse[3]=0; // no throttle reverse for safetyslow=digitalRead(sw_tog)==0 ?500:-500; // initial channel 6 value}for (ch=0; ch<4; ch++) {channel[ch] = map(analogRead(ch),stickcalLo[ch],stickcalHi[ch],-500,500); channel[ch] = constrain(channel[ch], -600, 600);} channel[4]=digitalRead(sw_btn)==0 ?500:-500; // channel 5if (digitalRead(sw_tog) == 0) {cchannel6 = 500;if (slow < 500) slow+=2;}if (digitalRead(sw_tog) == 1) {cchannel6 = -500;if (slow > -500) slow-=2;}channel[5]=slow; ch0val=channel[0];// check for reversing, stick over on power-up, not throttle though.if (startup==1) {for (ch=0; ch<3; ch++) {if (channel[ch] > 450 || channel[ch] < -450) { reverse[ch] ^=B00000001; EEPROM.write(16+ch,reverse[ch]);}}}// end of once-only startup routinesstartup=0;// read expo potexpo = map(analogRead(A6),0,1023,100,300); expo/=100;// read rates potrate = map(analogRead(A7),0,1023,100,10);rate/=100;for (ch=0; ch<3; ch++) {if (channel[ch] <0) {channel[ch]=abs(channel[ch])/500; channel[ch]=pow(channel[ch],expo)*-500; }elsechannel[ch]=(pow(channel[ch]/500,expo)*500);channel[ch]*=rate;}// do timed stuffif (cchannel6 != lastch6) {++flips; framecounter=0;}if (framecounter < 12 && flips >5) {rangetest ^= 1; // this flags the 3 flicks 'active'framecounter=12;}if (framecounter > 11) flips=0;lastch6=cchannel6;// format the framechannel[6]=0; // 6th element is syncfor (ch=0; ch<6; ch++) {channel[ch]+=neutralPulse;if (reverse[ch] ==1) channel[ch] = 2400-channel[ch];channel[6]+=channel[ch];}channel[6] = 15500-channel[6];chtemp=channel[3]; channel[3]=channel[2]; channel[2]=chtemp; // change channel order to Futaba AETRif (rangetest==1) {channel[2]=700; // throttle lowif (framecounter==50) {framecounter=0;flip^=1;}channel[0]=flip==0 ?800:1600;if (ch0val < -50 || ch0val > 50) rangetest=0;}// check if mixer switched inif (digitalRead(sw_mix) == 0) {channel[0]*=.75;channel[1]*=.25;chtemp=channel[1];channel[1]=channel[0]+600-channel[1];channel[0]+=chtemp;} //send ppm frame, last channel holds sync valuefor (int ch=0; ch<7; ch++) {digitalWrite(ppm, HIGH);delayMicroseconds(ppmPulse);digitalWrite(ppm, LOW);delayMicroseconds(channel[ch]);}if (framecounter<255) ++framecounter;// scope trigger pin 10, ensure mixer switched off, then temp define as OUTPUT in setup// digitalWrite(10, HIGH);// delayMicroseconds(100);// digitalWrite(10, LOW);}// This function will write a 2 byte integer to the eeprom at the specified address and address + 1void EEPROMWriteInt(int p_address, int p_value){byte lowByte = p_value%256;byte highByte = p_value/256;EEPROM.write(p_address, lowByte);EEPROM.write(p_address + 1, highByte);}//This function will read a 2 byte integer from the eeprom at the specified address and address + 1unsigned int EEPROMReadInt(int p_address){byte lowByte = EEPROM.read(p_address);byte highByte = EEPROM.read(p_address + 1);return lowByte + highByte*256;} 2. #define NB_WAY 6 // number of ways#define LOW_LENGTH 300 // How long last (in µs) a low between 2 pulses#define MIN_PPM_PULSE 1300 // minimum pulse length in µs#define PPM_PULSE_LENGTH 700 // how much more µs will last the max pulse length#define PACKET_LENGTH 21000 // How long (µs) last a full trame// trame length is fixed ! Every trame will make PACKET_LENGTH µs !// MUST NO BE MORE THAN 32ms !!! (timer's prescaler constraint)#define PPM_OUTPUT 13 // OUTPUT PINint way_value[NB_WAY];int way_pin[NB_WAY];int way_min[NB_WAY];int way_max[NB_WAY];int i = 0;int p = 0; // temp var for duty cycle calculationint last_i_timer = 0; // last way's value sent through PPM signalunsigned long int trame_elapsed_time = 0;bool output_state = LOW;void setup() {// ppm output :pinMode(PPM_OUTPUT, OUTPUT);digitalWrite(PPM_OUTPUT, output_state);// inits arraysfor(i=0;i<NB_WAY;i++){way_pin = 14 + i;pinMode(way_pin, INPUT);way_value = analogRead(way_pin);way_min = way_value;way_max = way_value;}// init timercli(); // desactivation interruptionsTCCR1A = 0x00; // set timer1 registers to 0TCCR1B = 0x00;TIMSK1 = 0x00;OCR1A = 65535;// set to the max// CTC mode:TCCR1B |= (1 << WGM12);// prescaler to 8, that allow (@16mhz) 32.8ms trameTCCR1B |= (0 << CS10);TCCR1B |= (1 << CS11);TCCR1B |= (0 << CS12);// timer activationTIMSK1 |= (1 << OCIE1A);sei();}ISR(TIMER1_COMPA_vect){TIMSK1 &= (0 << OCIE1A);if(output_state){ // END OF A HIGH, we have to wait LOW_LENGTH ms before next pulseoutput_state = LOW;digitalWrite(PPM_OUTPUT, output_state);OCR1A = 2 * LOW_LENGTH; // set when next timer interruption will occurTIMSK1 |= (1 << OCIE1A); // restart timertrame_elapsed_time += LOW_LENGTH;}else{ // END of a LOW_LENGTH, new pulse !output_state = HIGH;digitalWrite(PPM_OUTPUT, output_state);if(last_i_timer >= NB_WAY) // last way, so wait until next packet{OCR1A = (2 * PACKET_LENGTH) - (trame_elapsed_time * 2);// set when next timer interruption will occurTIMSK1 |= (1 << OCIE1A); // restart timerlast_i_timer = 0;trame_elapsed_time = 0;}else{OCR1A = 2 * way_value[last_i_timer];// set when next timer interruption will occurTIMSK1 |= (1 << OCIE1A); // restart timerlast_i_timer ++;trame_elapsed_time += way_value[NB_WAY];}}}void loop() {for(i=0;i<NB_WAY;i++){// Read current value of way i :p = analogRead(way_pin);// auto calibration...if(p > way_max) way_max = p;if(p < way_min) way_min = p;// Arduino map function sucksway_value = MIN_PPM_PULSE + PPM_PULSE_LENGTH * (float)((float)(p - way_min) / (float)(way_max - way_min));}} Editat Decembrie 14, 2014 de cippy Link spre comentariu
Mircea Postat Decembrie 14, 2014 Partajează Postat Decembrie 14, 2014 Nu lucrez cu Arduino, dar 1 nu foloseste, 2 foloseste.Pasionat de RC? Link spre comentariu
cippy Postat Decembrie 14, 2014 Autor Partajează Postat Decembrie 14, 2014 da, as dori sa realizez un encoder cu arduino... Link spre comentariu
Mircea Postat Decembrie 14, 2014 Partajează Postat Decembrie 14, 2014 (editat) Functie de o tensiune citita pe ADC (de la un joystick = potentiometru) generezi pulsul intre 1 si 2ms. Asta pentru inceput. Evident, mai multe canale, mai multe ADC citite. Apoi generezi secventa PPM pentru toate canalele, lasand un spatiu intre pulsuri.La decoder detectezi primul puls si activezi o iesire (canalul 1) corespondenta duratei pulsului. Apoi daca detectezi spatiul, treci la iesirea urmatoare (canalul 2), samd.Mai interesant este sa faci si setupul (programarea encoderului) si asta explica lungile programe de mai sus.De ce interesa care era cu intreruperi? Editat Decembrie 14, 2014 de thunderer Link spre comentariu
Postări Recomandate
Creează un cont sau autentifică-te pentru a adăuga comentariu
Trebuie să fi un membru pentru a putea lăsa un comentariu.
Creează un cont
Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!
Înregistrează un nou contAutentificare
Ai deja un cont? Autentifică-te aici.
Autentifică-te acum