Files
RepaJouets/CircuitCarreraCommande/arduinoNano_PWM/arduinoNano_PWM.ino

106 lines
4.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// High-frequency PWM using Timer2 on pins 3 & 11
const int pwmPin1 = 11; // OC2B
const int pwmPin2 = 3; // OC2A
bool readADC2 = true;
void setup() {
pinMode(pwmPin1, OUTPUT);
pinMode(pwmPin2, OUTPUT);
// ----- Timer2 Fast PWM (8-bit), no prescaler -----
TCCR2A = _BV(WGM20) | _BV(WGM21) | _BV(COM2A1) | _BV(COM2B1); // Fast PWM mode, enable PWM on Pin 11, enable PWM on Pin 3
//TCCR2B = _BV(CS20); // No prescaler → 16MHz / 256 = 62.5 kHz
TCCR2B = _BV(CS21); // Prescaler 8 → (16MHz / 8) / 256 = 7.812 kHz
ADCSRA = (1 << ADEN) | (1 << ADPS2); // Set ADC prescaler to 16 (1MHz ADC clock), 13 cycles to read a value so a readout takes 13 uS
// Atmel/Microchip recommends:
// 50200 kHz for full 10-bit accuracy
// Up to 1 MHz for reduced accuracy (≈ 89 bits)
Serial.begin(9600);
}
int currentSense2 = 0;
int currentSense3 = 0;
int countdownOffPWM1 = 1024;
int countdownOffPWM2 = 1024;
void loop() {
//int adc0 = analogRead(A0);
ADMUX = (1 << REFS0) | (A0 & 0x0F); // Set ADC reference to AVcc and channel to ADC channel 0, example REFS0 = 1 → 0100 0000 | Channel 3 → 0000 0011 | ADMUX → 0100 0011
ADCSRA |= (1 << ADSC); // Start ADC conversion
while (ADCSRA & (1 << ADSC))
; //wait or the ADC conversion to finish
int adc0 = ADC;
//int adc1 = analogRead(A1);
ADMUX = (1 << REFS0) | (A1 & 0x0F); // Set ADC reference to AVcc and channel to ADC channel 0, example REFS0 = 1 → 0100 0000 | Channel 3 → 0000 0011 | ADMUX → 0100 0011
ADCSRA |= (1 << ADSC); // Start ADC conversion
while (ADCSRA & (1 << ADSC))
; //wait or the ADC conversion to finish
int adc1 = ADC;
if (adc0 <= 100) { //Because the controller has noise on the ADC reading below this value and we want the cars to be still in position.
adc0 = 0;
}
if (adc1 <= 100) { //Because the controller has noise on the ADC reading below this value and we want the cars to be still in position.
adc1 = 0;
}
uint8_t pwm1 = map(adc0, 0, 1023, 0, 255);
uint8_t pwm2 = map(adc1, 0, 1023, 0, 255);
if (countdownOffPWM1 == 1024) {
OCR2B = pwm1; // Output is LOW from 0 to pwm1 value (between 0 and 256) and then goes HIGH from pwm1 value to 255 on Pin 3
} else {
countdownOffPWM1 = countdownOffPWM1 - 1;
if(countdownOffPWM1 == 0){
countdownOffPWM1 = 1024;
TCCR2A |= _BV(COM2A1); // Reconnect PWM to pin 11
}
}
if (countdownOffPWM1 == 1024) {
OCR2A = pwm2; // Output on pin 11 TCCR2A |= _BV(COM2B1);
}
else {
countdownOffPWM2 = countdownOffPWM2 - 1;
if(countdownOffPWM2 == 0){
countdownOffPWM2 = 1024;
TCCR2A |= _BV(COM2B1); // Reconnect PWM to pin 3
}
}
if (readADC2) { //Every two cycle we read ADC2 and ADC3
//int adc2 = analogRead(A2);
while (TCNT2 < 217); // wait until timer 2 is 20uS from resetting to perform the ADC conversion in 13 cycles thus in 13uS
ADMUX = (1 << REFS0) | (A2 & 0x0F); // Set ADC reference to AVcc and channel to ADC channel 0, example REFS0 = 1 → 0100 0000 | Channel 3 → 0000 0011 | ADMUX → 0100 0011
ADCSRA |= (1 << ADSC); // Start ADC conversion
while (ADCSRA & (1 << ADSC)); //wait or the ADC conversion to finish
currentSense2 = ADC;
if(currentSense2 > 128){
countdownOffPWM1 = 1023;
TCCR2A &= ~_BV(COM2A1); //Disable PWM from pin 11
PORTB &= ~_BV(PB3); // Pin 11 = PB3, force pin 11 LOW
}
readADC2 = false;
} else {
//int adc2 = analogRead(A3);
while (TCNT2 < 217); // wait until timer 2 is 20uS from resetting to perform the ADC conversion in 13 cycles thus in 13uS
ADMUX = (1 << REFS0) | (A3 & 0x0F); // Set ADC reference to AVcc and channel to ADC channel 0, example REFS0 = 1 → 0100 0000 | Channel 3 → 0000 0011 | ADMUX → 0100 0011
ADCSRA |= (1 << ADSC); // Start ADC conversion
while (ADCSRA & (1 << ADSC)); //wait or the ADC conversion to finish
currentSense3 = ADC;
if(currentSense3 > 128){
countdownOffPWM2 = 1023;
TCCR2A &= ~_BV(COM2B1);; //Disable PWM from pin 3
PORTD &= ~_BV(PD3); // Pin 3 = PD3, force pin 3 LOW
}
readADC2 = true;
}
} //end main loop