Sari la conținut
ELFORUM - Forumul electronistilor

Intrebare


cippy

Postări Recomandate

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 sticks
calibrated=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 safety
slow=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 5

if (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 routines
startup=0;

// read expo pot
expo = map(analogRead(A6),0,1023,100,300); expo/=100;
// read rates pot
rate = 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; }
else
channel[ch]=(pow(channel[ch]/500,expo)*500);
channel[ch]*=rate;
}

// do timed stuff
if (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 frame
channel[6]=0; // 6th element is sync
for (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 AETR

if (rangetest==1) {
channel[2]=700; // throttle low
if (framecounter==50) {
framecounter=0;
flip^=1;
}
channel[0]=flip==0 ?800:1600;
if (ch0val < -50 || ch0val > 50) rangetest=0;
}

// check if mixer switched in
if (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 value
for (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 + 1
void 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 + 1
unsigned 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 PIN

int 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 calculation
int last_i_timer = 0; // last way's value sent through PPM signal
unsigned long int trame_elapsed_time = 0;
bool output_state = LOW;

void setup() {
// ppm output :
pinMode(PPM_OUTPUT, OUTPUT);
digitalWrite(PPM_OUTPUT, output_state);

// inits arrays
for(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 timer
cli(); // desactivation interruptions
TCCR1A = 0x00; // set timer1 registers to 0
TCCR1B = 0x00;
TIMSK1 = 0x00;

OCR1A = 65535;// set to the max
// CTC mode:
TCCR1B |= (1 << WGM12);
// prescaler to 8, that allow (@16mhz) 32.8ms trame
TCCR1B |= (0 << CS10);
TCCR1B |= (1 << CS11);
TCCR1B |= (0 << CS12);
// timer activation
TIMSK1 |= (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 pulse
output_state = LOW;
digitalWrite(PPM_OUTPUT, output_state);
OCR1A = 2 * LOW_LENGTH; // set when next timer interruption will occur
TIMSK1 |= (1 << OCIE1A); // restart timer
trame_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 occur
TIMSK1 |= (1 << OCIE1A); // restart timer
last_i_timer = 0;
trame_elapsed_time = 0;
}
else
{
OCR1A = 2 * way_value[last_i_timer];// set when next timer interruption will occur
TIMSK1 |= (1 << OCIE1A); // restart timer
last_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 sucks
way_value = MIN_PPM_PULSE + PPM_PULSE_LENGTH * (float)((float)(p - way_min) / (float)(way_max - way_min));
}
}

Editat de cippy
Link spre comentariu
  • Răspunsuri 3
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

  • Mircea

    2

  • cippy

    2

Zile populare

Top autori în acest subiect

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 de thunderer
Link spre comentariu

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 cont

Autentificare

Ai deja un cont? Autentifică-te aici.

Autentifică-te acum



×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări