====== meca ====== {{:robots:tondobot:demontee.jpg?600|}} {{:robots:tondobot:arriere0.jpg?600|}} {{:robots:tondobot:arriere_monte.jpg?600|}} {{:robots:tondobot:face_monte.jpg?600|}} ===== moteur d"essuie glace ===== ==== a vide ==== * 13v 0,9 amp 58t/mn * 6v 0,6 amp 16t/mn test sur table a vide avec moteur de laguna: * petite vitesse 17 tours pour 30s * grande vitesse 32 tours pour 30s ====== HW ====== * https://www.ebay.fr/itm/Nano-V3-0-ATmega328P-with-USB-Cable-Compatible-for-Arduino-CH340G-Deutsche-Post/232271829785?ssPageName=STRK%3AMEBIDX%3AIT&_trksid=p2057872.m2749.l2649 * https://www.ebay.fr/itm/Semiconductor-BTS7960B-BTN7960-43A-H-Bridge-Stepper-Motor-Driver-PWM-For-Arduino/263076262942?ssPageName=STRK%3AMEBIDX%3AIT&_trksid=p2057872.m2749.l2649 * https://www.ebay.fr/itm/Battery-Protection-BMS-PCB-Board-For-10Packs-36V-10S-Li-ion-Cell-Max-40A-Balance/173401662933?ssPageName=STRK%3AMEBIDX%3AIT&_trksid=p2057872.m2749.l2649 {{:robots:tondobot:s-l1600.jpg?400|}} * [[https://www.amazon.fr/gp/product/B00ORLA7CO/ref=oh_aui_detailpage_o05_s00?ie=UTF8&psc=1 | DC-DC CC CV abaisseur Convertisseur Abaisseurs de tension module d'alimentation 7-32V a 0.8-28V 12A 300W ]] * [[https://www.amazon.fr/SODIAL-Abaisseur-Regulateur-Tension-Ajustable/dp/B00JGFEGG4/ref=sr_1_1?s=electronics&ie=UTF8&qid=1534783078&sr=1-1&keywords=SODIAL+%28R%29LM2596+DC-DC | LM2596 DC-DC Module Abaisseur Regulateur Tension Step Down CC-CV Ajustable]] ===== 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 ===== * https://www.robotshop.com/letsmakerobots/arduino-101-timers-and-interrupts old : https://arduino-info.wikispaces.com/Timers-Arduino * https://www.instructables.com/id/Arduino-Timer-Interrupts/ * http://sphinx.mythic-beasts.com/~markt/ATmega-timers.html ===== motor driver ===== * http://www.hessmer.org/blog/2013/12/28/ibt-2-h-bridge-with-arduino/ ==== PWM frequency ==== * https://www.instructables.com/id/Motor-Driver-BTS7960-43A/ changement de fréquence des PWM * https://www.arduino.cc/en/Tutorial/SecretsOfArduinoPWM === 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; ==== PID ==== * https://github.com/XRobots/WiperMotorServo * https://github.com/br3ttb/Arduino-PID-Library * http://playground.arduino.cc/Code/PIDLibrary * https://fr.mathworks.com/matlabcentral/fileexchange/4652-autotunerpid-toolkit ===== RC link ===== * https://www.arduino.cc/reference/en/#functions * https://create.arduino.cc/editor/ /* 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 ====== * https://github.com/nasa-jpl/open-source-rover * https://www.pololu.com/product/2591 optical encoder * https://www.pololu.com/product/3081 magnetic encoder * http://www.robot-maker.com/forum/topic/6355-cede-robot-tondeuse-pour-somme-modique/ * http://bennurre2.blogspot.com/ * http://bennurre4.blogspot.com/