Outils pour utilisateurs

Outils du site


robots:tondobot:tondobot

HW

Pinout Arduino Nano-V3

PCINT PWM Timer fnc fnc fnc fnc PCINT
PCINT2 TXD 1 VIN
PCINT2 RXD 0 GND
Reset RESET
GND 5V
servo_GD PCINT2 INT0 2 A7 Mot_D_IS_L (arriere)
servo_AVAR PCINT2 PWM_T2 INT2 3 A6 Mot_G_IS_L (arrierre)
ENC_G_B PCINT2 4 A5 D19/SCL PCINT1
ENC_D_A PCINT2 PWM_T0 5 A4 D18/SDA PCINT1
ENC_D_B PCINT2 PWM_T0 6 A3 D17 PCINT1 Mot_D_IS_R (avant)
Mot_D_L_EN PCINT2 7 A2 D16 PCINT1 Mot_G_IS_R (avant)
Mot_D_R_EN PCINT0 8 A1 D15 PCINT1
Mot_D_PWM PCINT0 PWM_T1 9 A0 D14 PCINT1 ENC_G_A
Mot_G_PWM PCINT0 PWM_T1 /SS 10 Aref
Mot_G_L_EN PCINT0 PWM_T2 MOSI 11 3v3
Mot_G_R_EN PCINT0 MISO 12 13 LED /SCK PCINT0 LED_PCB

Module BTS7960B

A. Nano FNC n n FNC A. Nano
Mot_X_R_EN RPWM 1 2 LPWM Mot_X_L_EN
Mot_X_PWM R_EN 3 4 L_EN Mot_X_PWM
Mot_X_IS_R R_IS 5 6 L_IS Mot_X_IS_L
VCC VCC 7 8 GND GND

SW

div

motor driver

PWM frequency

https://arduino-info.wikispaces.com/Arduino-PWM-Frequency (copy)

On the Arduino Duemilanove/UNO etc., pins 3,5,6, 9, 10, 11 can be configured for PWM output.

The 8-bit PWM value that you set when you call the analogWrite function:

analogWrite(myPWMpin, 128); Outputs a square wave

is compared against the value in an 8-bit counter. When the counter is less than the PWM value, the pin outputs a HIGH; when the counter is greater than the PWM value, the pin outputs a LOW. In the example above, a square wave is generated because the pin is HIGH from counts 0 to 127, and LOW from counts 128 to 255, so it is HIGH for the same amount of time it is LOW.

It follows logically that the frequency of the PWM signal is determined by the speed of the counter. Assuming you are using an Atmega168 with the Arduino Diecimila bootloader burned on it (which is exactly what you are using if you bought an Arduino Diecimila), this counter's clock is equal to the sytem clock divided by a prescaler value. The prescaler is a 3-bit value stored in the three least significant bits of the Timer/Counter register: CS02, CS01, and CS00. There are three such Timer/Counter registers: TCCR0B, TCCR1B, and TCCR2B.

Since there are three different prescalers, the six PWM pins are broken up into three pairs, each pair having its own prescaler. For instance, Arduion pins 6 and 5 are both controlled by TCCR0B, so you can set Arduino pins 6 and 5 to output a PWM signal at one frequency. Arduino pins 9 and 10 are controlled by TCCR1B, so they can be set at a different frequency from pins 6 and 5. Arduino pins 11 and 3 are controlled by TCCR2B, so they may be set at a third frequency. But you can't set different frequencies for pins that are controlled by the same prescaler (e.g. pins 6 and 5 must be at the same frequency).

If you use the default values set by the Arduino Diecimila's bootloader, these are your PWM frequencies:

Arduino Pins 5 and 6: 1kHz Arduino Pins 9, 10, 11, and 3: 500Hz

How do you change the PWM frequency?
In the void setup() part of your Arduino code, set or clear the CS02,CS01, and CS00 bits in the relevant TCCRnB register.
 
// For Arduino Uno, Nano, Micro Magician, Mini Driver, Lilly Pad and any other board using ATmega 8, 168 or 328**
//---------------------------------------------- Set PWM frequency for D5 & D6 -------------------------------
//TCCR0B = TCCR0B & B11111000 | B00000001;    // set timer 0 divisor to     1 for PWM frequency of 62500.00 Hz
//TCCR0B = TCCR0B & B11111000 | B00000010;    // set timer 0 divisor to     8 for PWM frequency of  7812.50 Hz
  TCCR0B = TCCR0B & B11111000 | B00000011;    // set timer 0 divisor to    64 for PWM frequency of   976.56 Hz (The DEFAULT)
//TCCR0B = TCCR0B & B11111000 | B00000100;    // set timer 0 divisor to   256 for PWM frequency of   244.14 Hz
//TCCR0B = TCCR0B & B11111000 | B00000101;    // set timer 0 divisor to  1024 for PWM frequency of    61.04 Hz
 
//---------------------------------------------- Set PWM frequency for D9 & D10 ------------------------------
//TCCR1B = TCCR1B & B11111000 | B00000001;    // set timer 1 divisor to     1 for PWM frequency of 31372.55 Hz
//TCCR1B = TCCR1B & B11111000 | B00000010;    // set timer 1 divisor to     8 for PWM frequency of  3921.16 Hz
  TCCR1B = TCCR1B & B11111000 | B00000011;    // set timer 1 divisor to    64 for PWM frequency of   490.20 Hz (The DEFAULT)
//TCCR1B = TCCR1B & B11111000 | B00000100;    // set timer 1 divisor to   256 for PWM frequency of   122.55 Hz
//TCCR1B = TCCR1B & B11111000 | B00000101;    // set timer 1 divisor to  1024 for PWM frequency of    30.64 Hz
 
//---------------------------------------------- Set PWM frequency for D3 & D11 ------------------------------
//TCCR2B = TCCR2B & B11111000 | B00000001;    // set timer 2 divisor to     1 for PWM frequency of 31372.55 Hz
//TCCR2B = TCCR2B & B11111000 | B00000010;    // set timer 2 divisor to     8 for PWM frequency of  3921.16 Hz
//TCCR2B = TCCR2B & B11111000 | B00000011;    // set timer 2 divisor to    32 for PWM frequency of   980.39 Hz
  TCCR2B = TCCR2B & B11111000 | B00000100;    // set timer 2 divisor to    64 for PWM frequency of   490.20 Hz (The DEFAULT)
//TCCR2B = TCCR2B & B11111000 | B00000101;    // set timer 2 divisor to   128 for PWM frequency of   245.10 Hz
//TCCR2B = TCCR2B & B11111000 | B00000110;    // set timer 2 divisor to   256 for PWM frequency of   122.55 Hz
//TCCR2B = TCCR2B & B11111000 | B00000111;    // set timer 2 divisor to  1024 for PWM frequency of    30.64 Hz
 
//For Arduino Mega1280, Mega2560, MegaADK, Spider or any other board using ATmega1280 or ATmega2560**
//---------------------------------------------- Set PWM frequency for D4 & D13 ------------------------------
//TCCR0B = TCCR0B & B11111000 | B00000001;    // set timer 0 divisor to     1 for PWM frequency of 62500.00 Hz
//TCCR0B = TCCR0B & B11111000 | B00000010;    // set timer 0 divisor to     8 for PWM frequency of  7812.50 Hz
  TCCR0B = TCCR0B & B11111000 | B00000011;    <// set timer 0 divisor to    64 for PWM frequency of   976.56 Hz (Default)
//TCCR0B = TCCR0B & B11111000 | B00000100;    // set timer 0 divisor to   256 for PWM frequency of   244.14 Hz
//TCCR0B = TCCR0B & B11111000 | B00000101;    // set timer 0 divisor to  1024 for PWM frequency of    61.04 Hz
 
//---------------------------------------------- Set PWM frequency for D11 & D12 -----------------------------
//TCCR1B = TCCR1B & B11111000 | B00000001;    // set timer 1 divisor to     1 for PWM frequency of 31372.55 Hz
//TCCR1B = TCCR1B & B11111000 | B00000010;    // set timer 1 divisor to     8 for PWM frequency of  3921.16 Hz
  TCCR1B = TCCR1B & B11111000 | B00000011;    // set timer 1 divisor to    64 for PWM frequency of   490.20 Hz
//TCCR1B = TCCR1B & B11111000 | B00000100;    // set timer 1 divisor to   256 for PWM frequency of   122.55 Hz
//TCCR1B = TCCR1B & B11111000 | B00000101;    // set timer 1 divisor to  1024 for PWM frequency of    30.64 Hz
 
//---------------------------------------------- Set PWM frequency for D9 & D10 ------------------------------
//TCCR2B = TCCR2B & B11111000 | B00000001;    // set timer 2 divisor to     1 for PWM frequency of 31372.55 Hz
//TCCR2B = TCCR2B & B11111000 | B00000010;    // set timer 2 divisor to     8 for PWM frequency of  3921.16 Hz
//TCCR2B = TCCR2B & B11111000 | B00000011;    // set timer 2 divisor to    32 for PWM frequency of   980.39 Hz
  TCCR2B = TCCR2B & B11111000 | B00000100;    // set timer 2 divisor to    64 for PWM frequency of   490.20 Hz
//TCCR2B = TCCR2B & B11111000 | B00000101;    // set timer 2 divisor to   128 for PWM frequency of   245.10 Hz
//TCCR2B = TCCR2B & B11111000 | B00000110;    // set timer 2 divisor to   256 for PWM frequency of   122.55 Hz
//TCCR2B = TCCR2B & B11111000 | B00000111;    // set timer 2 divisor to  1024 for PWM frequency of    30.64 Hz
 
//---------------------------------------------- Set PWM frequency for D2, D3 & D5 ---------------------------
//TCCR3B = TCCR3B & B11111000 | B00000001;    // set timer 3 divisor to     1 for PWM frequency of 31372.55 Hz
//TCCR3B = TCCR3B & B11111000 | B00000010;    // set timer 3 divisor to     8 for PWM frequency of  3921.16 Hz
  TCCR3B = TCCR3B & B11111000 | B00000011;    // set timer 3 divisor to    64 for PWM frequency of   490.20 Hz
//TCCR3B = TCCR3B & B11111000 | B00000100;    // set timer 3 divisor to   256 for PWM frequency of   122.55 Hz
//TCCR3B = TCCR3B & B11111000 | B00000101;    // set timer 3 divisor to  1024 for PWM frequency of    30.64 Hz
 
//---------------------------------------------- Set PWM frequency for D6, D7 & D8 ---------------------------
//TCCR4B = TCCR4B & B11111000 | B00000001;    // set timer 4 divisor to     1 for PWM frequency of 31372.55 Hz
//TCCR4B = TCCR4B & B11111000 | B00000010;    // set timer 4 divisor to     8 for PWM frequency of  3921.16 Hz
  TCCR4B = TCCR4B & B11111000 | B00000011;    // set timer 4 divisor to    64 for PWM frequency of   490.20 Hz
//TCCR4B = TCCR4B & B11111000 | B00000100;    // set timer 4 divisor to   256 for PWM frequency of   122.55 Hz
//TCCR4B = TCCR4B & B11111000 | B00000101;    // set timer 4 divisor to  1024 for PWM frequency of    30.64 Hz
 
//---------------------------------------------- Set PWM frequency for D44, D45 & D46 ------------------------
//TCCR5B = TCCR5B & B11111000 | B00000001;    // set timer 5 divisor to     1 for PWM frequency of 31372.55 Hz
//TCCR5B = TCCR5B & B11111000 | B00000010;    // set timer 5 divisor to     8 for PWM frequency of  3921.16 Hz
  TCCR5B = TCCR5B & B11111000 | B00000011;    // set timer 5 divisor to    64 for PWM frequency of   490.20 Hz
//TCCR5B = TCCR5B & B11111000 | B00000100;    // set timer 5 divisor to   256 for PWM frequency of   122.55 Hz
//TCCR5B = TCCR5B & B11111000 | B00000101;    // set timer 5 divisor to  1024 for PWM frequency of    30.64 Hz

PID

/*
Version avec 1 PWM et 2 enable par moteur
*/
#define PIN_SERVO_GD 2
#define PIN_SERVO_AVAR 3
 
#define PIN_MOT_D_PWM 9
#define PIN_MOT_D_L_EN 7    //sens arriere
#define PIN_MOT_D_R_EN 8    //sens avant
 
#define PIN_MOT_G_PWM 10
#define PIN_MOT_G_L_EN 11    //sens arriere
#define PIN_MOT_G_R_EN 12    //sens avant
 
#define PIN_MOT_D_L_IS A7     //sens arriere
#define PIN_MOT_G_L_IS A6     //sens arriere
#define PIN_MOT_D_R_IS A2     //sens avant
#define PIN_MOT_G_R_IS A3     //sens avant
 
 
volatile boolean SERVO_GD_New_pulse_IT,SERVO_AVAR_New_pulse_IT;
volatile unsigned long SERVO_GD_Pulse_micros_IT=0,SERVO_AVAR_Pulse_micros_IT=0;
unsigned long SERVO_GD_Pulse_micros=0,SERVO_AVAR_Pulse_micros=0;
unsigned long currentMillis;
unsigned long previousMillis = 0;
unsigned int LED_cnt_u16;
int MOT_D_CMD_s16,MOT_G_CMD_s16,CMD_AVAR,CMD_GD;
 
void update_MOT_D_PWMs(int cmd)
{
  if (cmd==0)
  {
     analogWrite(PIN_MOT_D_PWM, 0);
     digitalWrite(PIN_MOT_D_L_EN, LOW);
     digitalWrite(PIN_MOT_D_R_EN, LOW);
  }
    else if (cmd>0)
  {
     analogWrite(PIN_MOT_D_PWM, cmd);
     digitalWrite(PIN_MOT_D_L_EN, LOW);
     digitalWrite(PIN_MOT_D_R_EN, HIGH);
  }
  else
  {
     analogWrite(PIN_MOT_D_PWM, abs(cmd));
     digitalWrite(PIN_MOT_D_R_EN, LOW);
     digitalWrite(PIN_MOT_D_L_EN, HIGH);
  }
}
 
void update_MOT_G_PWMs(int cmd)
{ 
  if (cmd==0)
  {
     analogWrite(PIN_MOT_G_PWM, 0);
     digitalWrite(PIN_MOT_G_L_EN, LOW);
     digitalWrite(PIN_MOT_G_R_EN, LOW);
  }
    else if (cmd>0)
  {
     analogWrite(PIN_MOT_G_PWM, cmd);
     digitalWrite(PIN_MOT_G_L_EN, LOW);
     digitalWrite(PIN_MOT_G_R_EN, HIGH);
  }
  else
  {
     analogWrite(PIN_MOT_G_PWM, abs(cmd));
     digitalWrite(PIN_MOT_G_R_EN, LOW);
     digitalWrite(PIN_MOT_G_L_EN, HIGH);
  }
}
 
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
 
  pinMode(PIN_SERVO_GD, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(PIN_SERVO_GD), SERVO_GD_change_CB, CHANGE);
 
  pinMode(PIN_SERVO_AVAR, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(PIN_SERVO_AVAR), SERVO_AVAR_change_CB, CHANGE);
 
  pinMode(PIN_MOT_D_PWM, OUTPUT);
  pinMode(PIN_MOT_D_L_EN, OUTPUT);
  pinMode(PIN_MOT_D_R_EN, OUTPUT);
  pinMode(PIN_MOT_G_PWM, OUTPUT);
  pinMode(PIN_MOT_G_L_EN, OUTPUT);
  pinMode(PIN_MOT_G_R_EN, OUTPUT);
  update_MOT_D_PWMs(0);
  update_MOT_G_PWMs(0);
 
  pinMode(PIN_MOT_D_R_IS, INPUT);
  pinMode(PIN_MOT_D_L_IS, INPUT);
  pinMode(PIN_MOT_G_R_IS, INPUT);
  pinMode(PIN_MOT_G_L_IS, INPUT);
 
  Serial.begin(115200);
}
 
void SERVO_GD_change_CB() {
  static volatile unsigned long GD_rise_micros_IT = 0;
    if (digitalRead(PIN_SERVO_GD) == HIGH) {
      GD_rise_micros_IT = micros();
    }
    else {
      SERVO_GD_Pulse_micros_IT = micros();
      if (SERVO_GD_Pulse_micros_IT > GD_rise_micros_IT) SERVO_GD_Pulse_micros_IT -=GD_rise_micros_IT;
      else SERVO_GD_Pulse_micros_IT += (0xffffffff-GD_rise_micros_IT);//overflow of timer
      SERVO_GD_New_pulse_IT = true;
    }
}
 
void SERVO_AVAR_change_CB() {
  static volatile unsigned long AVAR_rise_micros_IT = 0;
    if (digitalRead(PIN_SERVO_AVAR) == HIGH) {
      AVAR_rise_micros_IT = micros();
    }
    else {
      SERVO_AVAR_Pulse_micros_IT = micros();
      if (SERVO_AVAR_Pulse_micros_IT > AVAR_rise_micros_IT) SERVO_AVAR_Pulse_micros_IT -=AVAR_rise_micros_IT;
      else SERVO_AVAR_Pulse_micros_IT += (0xffffffff-AVAR_rise_micros_IT);//overflow of timer
      SERVO_AVAR_New_pulse_IT = true;
    }
}
 
void loop() {
  delay(1); //wait 1ms
  currentMillis = millis();
 
  if (currentMillis - previousMillis >= 20) 
  { // 20ms task
    previousMillis = currentMillis;
 
    LED_cnt_u16++;
    if (LED_cnt_u16 % 100) digitalWrite(LED_BUILTIN, LOW);
    else digitalWrite(LED_BUILTIN, HIGH);
 
    //recuperation des dernieres commande servo
    noInterrupts();
      SERVO_GD_Pulse_micros=SERVO_GD_Pulse_micros_IT;
      SERVO_AVAR_Pulse_micros=SERVO_AVAR_Pulse_micros_IT;
    interrupts();
    //mise en borne et conversion des commande versos
    if (SERVO_GD_Pulse_micros < 850) SERVO_GD_Pulse_micros = 1500;  // pour traiter le cas ou on a pas de servo connecté
    if (SERVO_GD_Pulse_micros > 2200) SERVO_GD_Pulse_micros = 1500;  // pour traiter le cas ou on a pas de servo connecté
    if ((SERVO_GD_Pulse_micros > 1480) &&  (SERVO_GD_Pulse_micros < 1520))SERVO_GD_Pulse_micros = 1500; // pour avoir une zone neutre 
    SERVO_GD_Pulse_micros=constrain(SERVO_GD_Pulse_micros, 1000, 2000);
    CMD_GD = map(SERVO_GD_Pulse_micros,1000,2000,-255,255);
 
 
    if (SERVO_AVAR_Pulse_micros < 850) SERVO_AVAR_Pulse_micros = 1500;  // pour traiter le cas ou on a pas de servo connecté
    if (SERVO_AVAR_Pulse_micros > 2200) SERVO_AVAR_Pulse_micros = 1500;  // pour traiter le cas ou on a pas de servo connecté
    if ((SERVO_AVAR_Pulse_micros > 1480) &&  (SERVO_AVAR_Pulse_micros < 1520))SERVO_AVAR_Pulse_micros = 1500; // pour avoir une zone neutre 
    SERVO_AVAR_Pulse_micros=constrain(SERVO_AVAR_Pulse_micros, 1000, 2000);
    CMD_AVAR = map(SERVO_AVAR_Pulse_micros,1000,2000,-255,255);
 
    MOT_D_CMD_s16 = constrain(CMD_AVAR - CMD_GD,-255,255);
    MOT_G_CMD_s16 = constrain(CMD_AVAR + CMD_GD,-255,255);
 
    update_MOT_D_PWMs(MOT_D_CMD_s16);
    update_MOT_G_PWMs(MOT_G_CMD_s16);
 
    Serial.print("AVAR");
    Serial.print(SERVO_AVAR_Pulse_micros,DEC);
    Serial.print("\tGD");
    Serial.print(SERVO_GD_Pulse_micros,DEC);
    Serial.print("\tM_G");
    Serial.print(MOT_G_CMD_s16,DEC);
    Serial.print("\t");
    Serial.print(analogRead(PIN_MOT_G_L_IS));
    Serial.print("\t");
    Serial.print(analogRead(PIN_MOT_G_R_IS));
    Serial.print("\tM_D");
    Serial.print(MOT_D_CMD_s16,DEC);
    Serial.print("\t");
    Serial.print(analogRead(PIN_MOT_D_L_IS));
    Serial.print("\t");
    Serial.println(analogRead(PIN_MOT_D_R_IS));
    //Serial.print(analogRead(PIN_MOT_D_R_IS));
    //Serial.print("\r");
 
 
  } // end of task
 
}

idées

robots/tondobot/tondobot.txt · Dernière modification: 09/2018 par fred