Skip to main content
added 787 characters in body
Source Link
mike
  • 347
  • 6
  • 20

The minimal not workingMy testing code is:

// using a 16-bit timer to generate PWM signals for ESCs

// Phase Correct Mode counts from Bottom to Top and back to Bottom
// settingwith thea rangeprescaler toof 8
// motor signal (BOTTOMOCRnx) 0uses values of 1000 (idle) - 20482000 (TOPvaluemax)
// we need a prescalerwhich ofdirectly 8corresponds to get 488.28microseconds HzHIGH-time
// whichsetting isthe max,range sinceto 2000(BOTTOM) is0 nearly- fullTOPvalue dutycyclesets the frequency

// Motortwo signalimportant formulas are:
// frequency(OCRnxPWM) uses= valuesF_CPU of/ 1000-2000(2*Prescalar*TOPvalue)
//
// whichPulseWidth directly[s] corresponds= toHigh-tick-count microseconds/ HIGH(F_CPU/Prescalar)
// High-timetick-count = 2 * OCR-value

// n = number of timer (1,3)
// x = A,B,C


#include "Arduino.h"
// #include <Arduino.h>
// #define DEBUG
// #include <Moto.h>

#define PRESCALAR 8
#define PWM_FREQUENCY 50
#define TOP_VALUE F_CPU/(2*PRESCALAR*PWM_FREQUENCY)


uint16_t dutytime = 1000; // this gives idle throttle signal


void setup(void) {
  Serial.begin(115200);
  // moto.setup();

  // TIMER 1
  // TIMSK1 = 0; // disable Interrupts for timer1
  DDRB |= (1<<DDB5); // D9 Output
  DDRC |= (1<<DDC6); // D5 Output

  // set 1000ms to start motors in idle mode
  OCR1A = 1000L;
  OCR3A = 1000L;

  // bits 7,5,3 PWM Output on pins A,B,C respectively
  // bits 1,0 WGM_1,0: phase correction mode
  // TCCR1A |= 0x82;B10000010; // in hex: 0xAA for all 3 = 0bB 1010 1010
  TCCR1A |= (1<<COM1A1)|(1<<WGM11);
  // bit 4,3 WGM_3,2: phase correction mode
  // bits 2,1,0 Prescalar: 8
  // TCCR1B |= 0x12;B00010010; // 0bin hex: 0x12; B 0001 0010
  ICR1TCCR1B =|= 2500;(1<<WGM13)|(1<<CS11);
 // TOPvalueICR1 = 2500TOP_VALUE;

  // TIMER 3
  // TIMSK3 = 0; // disable Interrupts for timer3
  // bit 7 PWM Output on pin A
  // bits 1,0 WGM_1,0: phase correction mode
  TCCR3A |= B10000010; // in hex: 0x82; // 0bB 1000 0010
  // bit 4,3 WGM_3,2: phase correction mode
  // bits 2,1,0 Prescalar: 8
  TCCR3B |= 0x12;B00010010; // 0bin hex: 0x12; B 0001 0010
  ICR3 = 2500;TOP_VALUE; // TOPvalue = 2048

  OCR1A = dutytime;}//setup
  OCR3A

void =loop(void) dutytime;{

  // delaySerial.println(1000TOP_VALUE);
 
}  //setup


void loopdelay(void500) {;
  while (dutytime < 2000) {
    dutytime += 10;150;
    OCR1A = dutytime;
    OCR3A = dutytime;
    Serial.println(dutytime);
    delay(10001500);
  }
  while (dutytime > 1000) {
    dutytime -= 10;150;
    OCR1A = dutytime;
    OCR3A = dutytime;
    Serial.println(dutytime);
    delay(10001500);
  } 

}//loop

The minimal not working code is:

// using a 16-bit timer to generate PWM signals for ESCs

// Phase Correct Mode counts from Bottom to Top and back to Bottom
// setting the range to (BOTTOM) 0 - 2048 (TOPvalue)
// we need a prescaler of 8 to get 488.28 Hz
// which is max, since 2000 is nearly full dutycycle

// Motor signal (OCRnx) uses values of 1000-2000
// which directly corresponds to microseconds HIGH-time

// n = number of timer (1,3)
// x = A,B,C

uint16_t dutytime = 1000;


void setup(void) {
  // TIMER 1
  // TIMSK1 = 0; // disable Interrupts for timer1
  DDRB |= (1<<DDB5); // D9 Output
  DDRC |= (1<<DDC6); // D5 Output

  // bits 7,5,3 PWM Output on pins A,B,C respectively
  // bits 1,0 WGM_1,0: phase correction mode
  TCCR1A |= 0x82; //0xAA for all 3 = 0b 1010 1010
  // bit 4,3 WGM_3,2: phase correction mode
  // bits 2,1,0 Prescalar: 8
  TCCR1B |= 0x12; // 0b 0001 0010
  ICR1 = 2500; // TOPvalue = 2500

  // TIMER 3
  // TIMSK3 = 0; // disable Interrupts for timer3
  // bit 7 PWM Output on pin A
  // bits 1,0 WGM_1,0: phase correction mode
  TCCR3A |= 0x82; // 0b 1000 0010
  // bit 4,3 WGM_3,2: phase correction mode
  // bits 2,1,0 Prescalar: 8
  TCCR3B |= 0x12; // 0b 0001 0010
  ICR3 = 2500; // TOPvalue = 2048

  OCR1A = dutytime;
  OCR3A = dutytime;
  // delay(1000);
 
}//setup


void loop(void) {
  while (dutytime < 2000) {
    dutytime += 10;
    OCR1A = dutytime;
    OCR3A = dutytime;
    delay(1000);
  }
  while (dutytime > 1000) {
    dutytime -= 10;
    OCR1A = dutytime;
    OCR3A = dutytime;
    delay(1000);
  }
}//loop

My testing code is:

// using a 16-bit timer to generate PWM signals for ESCs

// Phase Correct Mode counts from Bottom to Top and back to Bottom
// with a prescaler of 8
// motor signal (OCRnx) uses values of 1000 (idle) - 2000 (max)
// which directly corresponds to microseconds HIGH-time
// setting the range to (BOTTOM) 0 - TOPvalue sets the frequency

// two important formulas are:
// frequency(PWM) = F_CPU / (2*Prescalar*TOPvalue)
//
// PulseWidth [s] = High-tick-count / (F_CPU/Prescalar)
// High-tick-count = 2 * OCR-value

// n = number of timer (1,3)
// x = A,B,C


#include "Arduino.h"
// #include <Arduino.h>
// #define DEBUG
// #include <Moto.h>

#define PRESCALAR 8
#define PWM_FREQUENCY 50
#define TOP_VALUE F_CPU/(2*PRESCALAR*PWM_FREQUENCY)


uint16_t dutytime = 1000; // this gives idle throttle signal


void setup(void) {
  Serial.begin(115200);
  // moto.setup();

  // TIMER 1
  // TIMSK1 = 0; // disable Interrupts for timer1
  DDRB |= (1<<DDB5); // D9 Output
  DDRC |= (1<<DDC6); // D5 Output

  // set 1000ms to start motors in idle mode
  OCR1A = 1000L;
  OCR3A = 1000L;

  // bits 7,5,3 PWM Output on pins A,B,C respectively
  // bits 1,0 WGM_1,0: phase correction mode
  // TCCR1A |= B10000010; // in hex: 0xAA for all 3 = B 1010 1010
  TCCR1A |= (1<<COM1A1)|(1<<WGM11);
  // bit 4,3 WGM_3,2: phase correction mode
  // bits 2,1,0 Prescalar: 8
  // TCCR1B |= B00010010; // in hex: 0x12; B 0001 0010
  TCCR1B |= (1<<WGM13)|(1<<CS11);
  ICR1 = TOP_VALUE;

  // TIMER 3
  // TIMSK3 = 0; // disable Interrupts for timer3
  // bit 7 PWM Output on pin A
  // bits 1,0 WGM_1,0: phase correction mode
  TCCR3A |= B10000010; // in hex: 0x82; // B 1000 0010
  // bit 4,3 WGM_3,2: phase correction mode
  // bits 2,1,0 Prescalar: 8
  TCCR3B |= B00010010; // in hex: 0x12; B 0001 0010
  ICR3 = TOP_VALUE; // TOPvalue = 2048

}//setup


void loop(void) {

  // Serial.println(TOP_VALUE);
  // delay(500);
  while (dutytime < 2000) {
    dutytime += 150;
    OCR1A = dutytime;
    OCR3A = dutytime;
    Serial.println(dutytime);
    delay(1500);
  }
  while (dutytime > 1000) {
    dutytime -= 150;
    OCR1A = dutytime;
    OCR3A = dutytime;
    Serial.println(dutytime);
    delay(1500);
  } 

}//loop
New info, Changed the desired update frequencies.
Source Link
mike
  • 347
  • 6
  • 20

I'm using the Registers of the Arduino micro to get a signal for Electronic Speed Controllers (ESC) for brushless motors. The idea is comming from the Multiwii project/various other online sourcesAs far as I read, ESCs interpret everything they can, while just ignoring too fast update rates. If somebody knows better, this would be a great time to yell.

The goal is to get a digital signal, where a timespan between 1 and 2 ms is HIGH and the rest low. Ideally I want this at 488Hz50-400Hz, since then 2ms HIGH488Hz is nearly 100% duty cycle and thus the fastest possible frequency, and 50 Hz the standard Servo frequency.

I try to use Phase Correct Mode to count up and down continuously. As the value in the counter reaches my set OCRnx on the way up, it sets the output pin LOW, as it reaches the same value on the way down, after reaching TOP(value), it sets the output HIGH. This is how I understand it. If not correctIn ATmega documentation terms, please help me out herethis is NON-inverted Phase-Correct-PWM.

So I set the Registers DDR (to set the pin as output), TCCR1A and TCCR1B and ICR1 (TOPvalue = 2048 = 0x800between 20000 and 2500).

Now using OCR1A = 1000 should give me a pulse width of 1000ms at a sample rate of 488.28Hz. This is the expected or target behaviour.

// using a 16-bit timer to generate PWM signals for ESCs

// Phase Correct Mode counts from Bottom to Top and back to Bottom
// setting the range to (BOTTOM) 0 - 2048 (TOPvalue)
// we need a prescaler of 8 to get 488.28 Hz
// which is max, since 2000 is nearly full dutycycle

// Motor signal (OCRnx) uses values of 1000-2000
// which directly corresponds to microseconds HIGH-time

// n = number of timer (1,3)
// x = A,B,C

uint16_t dutytime = 1000;


void setup(void) {
  // TIMER 1
  // TIMSK1 = 0; // disable Interrupts for timer1
  DDRB |= (1<<DDB5); // D9 Output
  DDRC |= (1<<DDC6); // D5 Output

  // bits 7,5,3 PWM Output on pins A,B,C respectively
  // bits 1,0 WGM_1,0: phase correction mode
  TCCR1A |= 0x82; //0xAA for all 3 = 0b 1010 1010
  // bit 4,3 WGM_3,2: phase correction mode
  // bits 2,1,0 Prescalar: 8
  TCCR1B |= 0x12; // 0b 0001 0010
  ICR1 = 0x800;2500; // TOPvalue = 20482500

  // TIMER 3
  // TIMSK3 = 0; // disable Interrupts for timer3
  // bit 7 PWM Output on pin A
  // bits 1,0 WGM_1,0: phase correction mode
  TCCR3A |= 0x82; // 0b 1000 0010
  // bit 4,3 WGM_3,2: phase correction mode
  // bits 2,1,0 Prescalar: 8
  TCCR3B |= 0x12; // 0b 0001 0010
  ICR3 = 0x800;2500; // TOPvalue = 2048

  OCR1A = dutytime;
  OCR3A = dutytime;
  // delay(1000);

}//setup


void loop(void) {
  while (dutytime < 2000) {
    dutytime += 10;
    OCR1A = dutytime;
    OCR3A = dutytime;
    delay(1000);
  }
  while (dutytime > 1000) {
    dutytime -= 10;
    OCR1A = dutytime;
    OCR3A = dutytime;
    delay(1000);
  }
}//loop

I'm using the Registers of the Arduino micro to get a signal for Electronic Speed Controllers (ESC) for brushless motors. The idea is comming from the Multiwii project/various other online sources.

The goal is to get a digital signal, where a timespan between 1 and 2 ms is HIGH and the rest low. Ideally I want this at 488Hz, since then 2ms HIGH is nearly 100% duty cycle and thus the fastest possible frequency.

I try to use Phase Correct Mode to count up and down continuously. As the value in the counter reaches my set OCRnx on the way up, it sets the output pin LOW, as it reaches the same value on the way down, after reaching TOP(value), it sets the output HIGH. This is how I understand it. If not correct, please help me out here.

So I set the Registers DDR (to set the pin as output), TCCR1A and TCCR1B and ICR1 (TOPvalue = 2048 = 0x800).

Now using OCR1A = 1000 should give me a pulse width of 1000ms at a sample rate of 488.28Hz. This is the expected or target behaviour.

// using a 16-bit timer to generate PWM signals for ESCs

// Phase Correct Mode counts from Bottom to Top and back to Bottom
// setting the range to (BOTTOM) 0 - 2048 (TOPvalue)
// we need a prescaler of 8 to get 488.28 Hz
// which is max, since 2000 is nearly full dutycycle

// Motor signal (OCRnx) uses values of 1000-2000
// which directly corresponds to microseconds HIGH-time

// n = number of timer (1,3)
// x = A,B,C

uint16_t dutytime = 1000;


void setup(void) {
  // TIMER 1
  // TIMSK1 = 0; // disable Interrupts for timer1
  DDRB |= (1<<DDB5); // D9 Output
  DDRC |= (1<<DDC6); // D5 Output

  // bits 7,5,3 PWM Output on pins A,B,C respectively
  // bits 1,0 WGM_1,0: phase correction mode
  TCCR1A |= 0x82; //0xAA for all 3 = 0b 1010 1010
  // bit 4,3 WGM_3,2: phase correction mode
  // bits 2,1,0 Prescalar: 8
  TCCR1B |= 0x12; // 0b 0001 0010
  ICR1 = 0x800; // TOPvalue = 2048

  // TIMER 3
  // TIMSK3 = 0; // disable Interrupts for timer3
  // bit 7 PWM Output on pin A
  // bits 1,0 WGM_1,0: phase correction mode
  TCCR3A |= 0x82; // 0b 1000 0010
  // bit 4,3 WGM_3,2: phase correction mode
  // bits 2,1,0 Prescalar: 8
  TCCR3B |= 0x12; // 0b 0001 0010
  ICR3 = 0x800; // TOPvalue = 2048

  OCR1A = dutytime;
  OCR3A = dutytime;
  // delay(1000);

}//setup


void loop(void) {
  while (dutytime < 2000) {
    dutytime += 10;
    OCR1A = dutytime;
    OCR3A = dutytime;
    delay(1000);
  }
  while (dutytime > 1000) {
    dutytime -= 10;
    OCR1A = dutytime;
    OCR3A = dutytime;
    delay(1000);
  }
}//loop

I'm using the Registers of the Arduino micro to get a signal for Electronic Speed Controllers (ESC) for brushless motors. As far as I read, ESCs interpret everything they can, while just ignoring too fast update rates. If somebody knows better, this would be a great time to yell.

The goal is to get a digital signal, where a timespan between 1 and 2 ms is HIGH and the rest low. Ideally I want this at 50-400Hz, since 488Hz is the fastest possible frequency, and 50 Hz the standard Servo frequency.

I try to use Phase Correct Mode to count up and down continuously. As the value in the counter reaches my set OCRnx on the way up, it sets the output pin LOW, as it reaches the same value on the way down, after reaching TOP(value), it sets the output HIGH. In ATmega documentation terms, this is NON-inverted Phase-Correct-PWM.

So I set the Registers DDR (to set the pin as output), TCCR1A and TCCR1B and ICR1 (TOPvalue = between 20000 and 2500).

Now using OCR1A = 1000 should give me a pulse width of 1000ms. This is the expected or target behaviour.

// using a 16-bit timer to generate PWM signals for ESCs

// Phase Correct Mode counts from Bottom to Top and back to Bottom
// setting the range to (BOTTOM) 0 - 2048 (TOPvalue)
// we need a prescaler of 8 to get 488.28 Hz
// which is max, since 2000 is nearly full dutycycle

// Motor signal (OCRnx) uses values of 1000-2000
// which directly corresponds to microseconds HIGH-time

// n = number of timer (1,3)
// x = A,B,C

uint16_t dutytime = 1000;


void setup(void) {
  // TIMER 1
  // TIMSK1 = 0; // disable Interrupts for timer1
  DDRB |= (1<<DDB5); // D9 Output
  DDRC |= (1<<DDC6); // D5 Output

  // bits 7,5,3 PWM Output on pins A,B,C respectively
  // bits 1,0 WGM_1,0: phase correction mode
  TCCR1A |= 0x82; //0xAA for all 3 = 0b 1010 1010
  // bit 4,3 WGM_3,2: phase correction mode
  // bits 2,1,0 Prescalar: 8
  TCCR1B |= 0x12; // 0b 0001 0010
  ICR1 = 2500; // TOPvalue = 2500

  // TIMER 3
  // TIMSK3 = 0; // disable Interrupts for timer3
  // bit 7 PWM Output on pin A
  // bits 1,0 WGM_1,0: phase correction mode
  TCCR3A |= 0x82; // 0b 1000 0010
  // bit 4,3 WGM_3,2: phase correction mode
  // bits 2,1,0 Prescalar: 8
  TCCR3B |= 0x12; // 0b 0001 0010
  ICR3 = 2500; // TOPvalue = 2048

  OCR1A = dutytime;
  OCR3A = dutytime;
  // delay(1000);

}//setup


void loop(void) {
  while (dutytime < 2000) {
    dutytime += 10;
    OCR1A = dutytime;
    OCR3A = dutytime;
    delay(1000);
  }
  while (dutytime > 1000) {
    dutytime -= 10;
    OCR1A = dutytime;
    OCR3A = dutytime;
    delay(1000);
  }
}//loop
Tweeted twitter.com/#!/StackArduino/status/519670406051950592
added 219 characters in body
Source Link
mike
  • 347
  • 6
  • 20

The goal is to get a digital signal, where a timespan between 1 and 2 ms is HIGH and the rest low. Ideally I want this at 488Hz, since then 2ms HIGH is nearly 100% duty cycle and thus the fastest possible frequency.

I try to use Phase Correct Mode to count up and down continuously. As the value in the counter reaches my set OCRnx on the way up, it sets the output pin LOW, as it reaches the same value on the way down, after reaching TOP(value), it sets the output HIGH. This is how I understand it. If not correct, please help me out here.

I try to use Phase Correct Mode to count up and down continuously. As the value in the counter reaches my set OCRnx on the way up, it sets the output pin LOW, as it reaches the same value on the way down, after reaching TOP(value), it sets the output HIGH. This is how I understand it. If not correct, please help me out here.

The goal is to get a digital signal, where a timespan between 1 and 2 ms is HIGH and the rest low. Ideally I want this at 488Hz, since then 2ms HIGH is nearly 100% duty cycle and thus the fastest possible frequency.

I try to use Phase Correct Mode to count up and down continuously. As the value in the counter reaches my set OCRnx on the way up, it sets the output pin LOW, as it reaches the same value on the way down, after reaching TOP(value), it sets the output HIGH. This is how I understand it. If not correct, please help me out here.

edited title
Link
mike
  • 347
  • 6
  • 20
Loading
Source Link
mike
  • 347
  • 6
  • 20
Loading