probleem met code voor motor driver

algemene C code
Berichten: 6
Geregistreerd: 01 Sep 2017, 20:58

probleem met code voor motor driver

Berichtdoor hepost » 01 Sep 2017, 21:15

Voor een modelbaantje wil ik een arduino nano met een l298n motor driver board gebruiken. De rijrichting wordt aangegeven d.m.v. een aan-uit-aan tuimelschakelaar. Na wat experimenteren heb ik het onderstaande werkend gekregen. Mijn probleem is zodra ik de code voor de regelaar voor motor B erbij zet dit niet meer werkt. Ik kopieer de code voor rijregelaar A in de loop en pas dat aan voor rijregelaar B. Ik krijg geen foutmeldingen tijdens het verifieren. Mijn kennis over programmeren schiet nu ernstig tekort om dit op te lossen. Hoe kan ik beide H-bruggen aansturen met de arduino met 2 aan-uit-aan schakelaars en 2 potmeters?

Code: Alles selecteren
#include <Bounce2.h>

int P_SPEEDA = 14; //potmeter A
int P_SPEEDB = 15; //potmeter B
const byte enA = 6; //pwmA uitgang
const byte enB = 9; //pwmB uitgang
const byte in1 = 4;
const byte in2 = 5;
const byte in3 = 10;
const byte in4 = 11;
#define dirA_F 7 //pin schakelaar A vooruit
#define dirA_R 8 //pin schakelaar A achteruit
#define dirB_F 12 //pin schakelaar B vooruit
#define dirB_R 13 //pin schakelaar B achteruit
const int L_ESTOP = 3; //pin led noodstop


int pwmA;
int pwmB;

// Instantiate a Bounce object
Bounce debouncer1 = Bounce();
Bounce debouncer2 = Bounce();
Bounce debouncer3 = Bounce();
Bounce debouncer4 = Bounce();

//----------------------------------------------------------------------------------------------------------

void setup(){
Serial.begin(9600);
delay(100);

//TCCR0B = TCCR0B & B11111000 | B00000001;    // set timer 0 divisor to     1 for pwmA frequency of 62500.00 Hz
//TCCR0B = TCCR0B & B11111000 | B00000010;    // set timer 0 divisor to     8 for pwmA frequency of  7812.50 Hz
TCCR0B = TCCR0B & B11111000 | B00000101;    // set timer 0 divisor to     1024 for pwmA frequency of  61.04 Hz op pin 5 en 6
TCCR1B = TCCR1B & B11111000 | B00000101;    // set timer 0 divisor to     1024 for pwmA frequency of  30.64 Hz op pin 9 en 10

pinMode(enA,OUTPUT);
pinMode(in1,OUTPUT);
pinMode(in2,OUTPUT);
pinMode(dirA_F,INPUT);
pinMode(dirA_R,INPUT);
pinMode(dirB_F,INPUT);
pinMode(dirB_R,INPUT);
pinMode(L_ESTOP,OUTPUT); //led noodstop

debouncer1.attach(dirA_F);
  debouncer1.interval(5); // interval in ms
debouncer2.attach(dirA_R);
  debouncer2.interval(5); // interval in ms
}

//------------------------------------------------------------------------------------------------------------
void loop() {

debouncer1.update();
debouncer2.update();

// Get the updated value :
  int value1 = debouncer1.read();
  int value2 = debouncer2.read();


//bepalen van de rijrichting regelaar A
if(value1==HIGH){
  digitalWrite(in1,LOW);
  digitalWrite(in2,HIGH);
  Serial.println("A vooruit");
  }
else if(value2==HIGH){
  digitalWrite(in1,HIGH);
  digitalWrite(in2,LOW);
  Serial.println("A achteruit");
  }
else{
  digitalWrite(in1,LOW);
  digitalWrite(in2,LOW);
  Serial.println("A stop");
  }

//snelheid A
pwmA=analogRead(P_SPEEDA)/4; //0 tot 1023 gedeeld door 4  = 0 tm 255
if(pwmA>255) pwmA=255;
if(pwmA<0) pwmA=0;
analogWrite(enA,pwmA);
//Serial.println(pwmA);
}

Advertisement

Berichten: 6
Geregistreerd: 01 Sep 2017, 20:58

Re: probleem met code voor motor driver

Berichtdoor hepost » 01 Sep 2017, 21:19

Dit is de code die ik heb voor beide regelaars.

Code: Alles selecteren
#include <Bounce2.h>

int P_SPEEDA = 14; //potmeter A
int P_SPEEDB = 15; //potmeter B
const byte enA = 6; //pwmA uitgang
const byte enB = 9; //pwmB uitgang
const byte in1 = 4;
const byte in2 = 5;
const byte in3 = 10;
const byte in4 = 11;
#define dirA_F 7 //pin schakelaar A vooruit
#define dirA_R 8 //pin schakelaar A achteruit
#define dirB_F 12 //pin schakelaar B vooruit
#define dirB_R 13 //pin schakelaar B achteruit
const int L_ESTOP = 3; //pin led noodstop


int pwmA;
int pwmB;

// Instantiate a Bounce object
Bounce debouncer1 = Bounce();
Bounce debouncer2 = Bounce();
Bounce debouncer3 = Bounce();
Bounce debouncer4 = Bounce();

//----------------------------------------------------------------------------------------------------------

void setup(){
Serial.begin(9600);
delay(100);

//TCCR0B = TCCR0B & B11111000 | B00000001;    // set timer 0 divisor to     1 for pwmA frequency of 62500.00 Hz
//TCCR0B = TCCR0B & B11111000 | B00000010;    // set timer 0 divisor to     8 for pwmA frequency of  7812.50 Hz
TCCR0B = TCCR0B & B11111000 | B00000101;    // set timer 0 divisor to     1024 for pwmA frequency of  61.04 Hz op pin 5 en 6
TCCR1B = TCCR1B & B11111000 | B00000101;    // set timer 0 divisor to     1024 for pwmA frequency of  30.64 Hz op pin 9 en 10

pinMode(enA,OUTPUT);
pinMode(in1,OUTPUT);
pinMode(in2,OUTPUT);
pinMode(dirA_F,INPUT);
pinMode(dirA_R,INPUT);
pinMode(dirB_F,INPUT);
pinMode(dirB_R,INPUT);
pinMode(L_ESTOP,OUTPUT); //led noodstop

debouncer1.attach(dirA_F);
  debouncer1.interval(5); // interval in ms
debouncer2.attach(dirA_R);
  debouncer2.interval(5); // interval in ms
debouncer3.attach(dirB_F);
  debouncer3.interval(5); // interval in ms
debouncer4.attach(dirB_R);
  debouncer4.interval(5); // interval in ms
}

//------------------------------------------------------------------------------------------------------------
void loop() {

debouncer1.update();
debouncer2.update();
debouncer3.update();
debouncer4.update();

// Get the updated value :
  int value1 = debouncer1.read();
  int value2 = debouncer2.read();
  int value3 = debouncer2.read();
  int value4 = debouncer2.read();

//bepalen van de rijrichting regelaar A
if(value1==HIGH){
  digitalWrite(in1,LOW);
  digitalWrite(in2,HIGH);
  Serial.println("A vooruit");
  }
else if(value2==HIGH){
  digitalWrite(in1,HIGH);
  digitalWrite(in2,LOW);
  Serial.println("A achteruit");
  }
else{
  digitalWrite(in1,LOW);
  digitalWrite(in2,LOW);
  Serial.println("A stop");
  }

//snelheid A
pwmA=analogRead(P_SPEEDA)/4; //0 tot 1023 gedeeld door 4  = 0 tm 255
if(pwmA>255) pwmA=255;
if(pwmA<0) pwmA=0;
analogWrite(enA,pwmA);
//Serial.println(pwmA);

//bepalen van de rijrichting regelaar B
if(value3==HIGH){
  digitalWrite(in3,LOW);
  digitalWrite(in4,HIGH);
  Serial.println("B vooruit");
  }
else if(value4==HIGH){
  digitalWrite(in3,HIGH);
  digitalWrite(in4,LOW);
  Serial.println("B achteruit");
  }
else{
  digitalWrite(in3,LOW);
  digitalWrite(in4,LOW);
  Serial.println("B stop");
  }

//snelheid B
pwmA=analogRead(P_SPEEDB)/4; //0 tot 1023 gedeeld door 4  = 0 tm 255
if(pwmB>255) pwmB=255;
if(pwmB<0) pwmB=0;
analogWrite(enB,pwmB);
//Serial.println(pwmB);
}

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: probleem met code voor motor driver

Berichtdoor Koepel » 02 Sep 2017, 13:32

Dit is voor ons lastig om te beantwoorden. Je sketch is maar een deel van wat er mis kan gaan.

Je wilt meteen vooruit springen naar iets dat helemaal werkt, dat doet geen enkele ervaren programmeur. Doe het stapje voor stapje.
Het is normaal om een stuk of vijf verschillende sketchjes te hebben om bepaalde dingen te proberen.
Wanneer je een sketch maakt voor alleen motor 'B', werkt die dan ?
Wanneer je onderaan de loop() een delay(500); toevoegt en de analoge waarde naar de seriele poort stuurt, kloppen dan de waarden ?

Wanneer dat niet werkt, dan doe je een flinke stap terug en probeer je motor 'A' en 'B' te laten draaien met een zo eenvoudig mogelijk sketch. Dus met pinMode(), digitalWrite() en analogWrite() en weinig meer.

Het rommelen met TCCR0B en TCCR1B is een optimalisatie. Dat is iets voor later als alles werkt. Wanneer iets niet werkt, dan is de eerste stap om alle rare fratsen even uit te zetten.

Wanneer je een analog pin gebruikt, gebruik dan bij voorkeur A0 en A1 in plaats van 14 en 15. De pin 'A0' heeft het label 'A0', dus dat is zijn naam. Dan is het logischer om dat ook in de sketch te gebruiken.

Probeer te vertellen wat je doet en wat het resultaat is. Wanneer je schrijft dat het niet meer werkt, dan haken sommigen af.

Hoe zit het met de hardware ? De voltages, welke motors, hoe is het verbonden, heb je genoeg ampere voor de motors, heb je een grounding probleem, gebruik je een shield met de L298N of een module en welk shield en welke module dan, doe je aparte dingen met de Arduino Nano, is het een echte Nano of een clone en zo ja welke clone, enzovoorts, enzovoorts, enzovoorts. Ik kan tientallen van zulke vragen stellen :o

Omdat je waarschijnlijk met voltages werkt die hoger zijn dan 5V, is het mogelijk dat de Nano stuk is gegaan. De hele Nano kan stuk zijn, of een deel of een enkele pin. Hoeveel reserve Arduino boards heb je liggen ;)

Berichten: 6
Geregistreerd: 01 Sep 2017, 20:58

Re: probleem met code voor motor driver

Berichtdoor hepost » 05 Sep 2017, 20:46

Hallo,

Even over de hardware: een arduino nano (kloon), een motor driver module met een L298n H-brug (een goedkope uit China). 2x 10k potmeters voor de rijsnelheid van A en B en 2 aan-uit-aan schakelaars voor de rijrichting van A en B. Gestabiliseerde netvoeding 12v dc, max. 2A voor de rijstroom. 9v 1A adapter voor de voeding van de arduino. Verbruik van de treintjes zal maximaal 0,5A zijn. H-brug is geaard aan de arduino.

Ik had al verschillende sketches gemaakt waarbij ik de onderlinge onderdelen wel werkend kreeg. Bij het testen gebruikte ik een 12v motortje en het werkte allemaal prachtig. Toen ik de boel echter aansloot op de modelbaan en het treintje wilde laten rijden ging er iets fout, het treintje bleef stil staan, bromde iets en er kwam op een gegeven moment wat rook uit. Na wat gezoek op internet kwam ik er achter dat het treintje waarschijnlijk niet tegen hoge frequenties kan (kleef).
Na wat experimenteren kwam ik op de frequentie van 30-60 Hertz om de trein in beweging te krijgen. Ik heb de timer 0 en timer 1 aangepast, misschien dat er daardoor iets mis ging. De frequentie kon ik eerst niet lager zetten maar naar wat zoeken op internet is me dat toch gelukt. Zie http://www.oxgadgets.com/2011/04/creating-a-variable-frequency-pwm-output-on-arduino-uno.html.

Inmiddels heb ik de code veranderd en alleen timer 1 aangepast. Daarnaast heb ik de frequentie regelbaar gemaakt. De pwm uitgangen dus op pin 9 en 10. Nu werken beide rijregelaars wel.


De huidige code ziet er als volgt uit:

Code: Alles selecteren
#include <Bounce2.h>

//Deze code werkt op een Arduino Uno/nano rev.3 met een L298n h-brug module.
//frequentieregeling gebaseerd op code van http://www.oxgadgets.com/2011/04/creating-a-variable-frequency-pwm-output-on-arduino-uno.html

//pin setup
int P_SPEEDA = A0; //potmeter A
int P_SPEEDB = A1; //potmeter B
int freq = A2; //potmeter voor frequentieregeling
const byte enA = 9; //enable A op h-brug
const byte enB = 10; //enable B op h-brug
const byte in1 = 3;
const byte in2 = 4;
const byte in3 = 5;
const byte in4 = 6;
#define dirA_F 7 //pin schakelaar A vooruit
#define dirA_R 8 //pin schakelaar A achteruit
#define dirB_F 11 //pin schakelaar B vooruit
#define dirB_R 12 //pin schakelaar B achteruit


// debounce voor de schakelaars
Bounce debouncer1 = Bounce();
Bounce debouncer2 = Bounce();
Bounce debouncer3 = Bounce();
Bounce debouncer4 = Bounce();

unsigned long duty1,duty2; // Duty Cycle in percentage.
unsigned long pwm1; // Value read from A0 and A2 to give PWM duty cycle output in terms // of 0-5V
unsigned long pwm2;
float xxx; // Float numbers to calculate duty for PWM 1 and PWM 2
float yyy;
int freqmap = 0;

//SETUP-----------SETUP-----------SETUP-----------SETUP-----------SETUP-----------SETUP

void setup(){
Serial.begin(9600);
delay(100);

TCCR1A = _BV(COM1A1) | _BV(COM1B1) ; // phase and frequency correct mode. NON-inverted mode
// TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(COM1A0) | _BV(COM1B0) ;
//phase/frequency correct mode. SELECT THIS FOR INVERTED OUTPUTS.
TCCR1B = _BV(WGM13) | _BV(CS11);
// Select mode 8 and select divide by 8 on main clock.

pinMode(enA,OUTPUT);
pinMode(enB,OUTPUT);
pinMode(in1,OUTPUT);
pinMode(in2,OUTPUT);
pinMode(in3,OUTPUT);
pinMode(in4,OUTPUT);
pinMode(dirA_F,INPUT);
pinMode(dirA_R,INPUT);
pinMode(dirB_F,INPUT);
pinMode(dirB_R,INPUT);

debouncer1.attach(dirA_F);
  debouncer1.interval(5); // interval in ms
debouncer2.attach(dirA_R);
  debouncer2.interval(5); // interval in ms
debouncer3.attach(dirB_F);
  debouncer3.interval(5); // interval in ms
debouncer4.attach(dirB_R);
  debouncer4.interval(5); // interval in ms
}

//LOOP-----------LOOP-----------LOOP-----------LOOP-----------LOOP
void loop() {

debouncer1.update();
debouncer2.update();
debouncer3.update();
debouncer4.update();

// Get the updated value:
  int value1 = debouncer1.read();
  int value2 = debouncer2.read();
  int value3 = debouncer2.read();
  int value4 = debouncer2.read();

//bepalen van de rijrichting regelaar A
if(value1==HIGH){
  digitalWrite(in1,LOW);
  digitalWrite(in2,HIGH);
  Serial.println("A vooruit");
  }
else if(value2==HIGH){
  digitalWrite(in1,HIGH);
  digitalWrite(in2,LOW);
  Serial.println("A achteruit");
  }
else{
  digitalWrite(in1,LOW);
  digitalWrite(in2,LOW);
  Serial.println("A stop");
  }

//bepalen van de rijrichting regelaar B
if(value3==HIGH){
  digitalWrite(in3,LOW);
  digitalWrite(in4,HIGH);
  Serial.println("B vooruit");
  }
else if(value4==HIGH){
  digitalWrite(in3,HIGH);
  digitalWrite(in4,LOW);
  Serial.println("B achteruit");
  }
else{
  digitalWrite(in3,LOW);
  digitalWrite(in4,LOW);
  Serial.println("B stop");
  }

//frequentieregeling en snelheid
freqmap = analogRead(freq);
ICR1 = map(freqmap, 0, 1023, 15000 , 5000); // 50000 = 20Hz en 10000 = 100Hz
//Serial.println(ICR1);           


pwm1 = analogRead(P_SPEEDA);
pwm2 = analogRead(P_SPEEDB);
xxx = float(pwm1);
// Turn read values from the POTs to float for mathematical
// adjustment.
yyy = float(pwm2);
xxx = xxx * ICR1;
// Multiply with ICR1 and divide by 1023 to give required percentage
yyy = yyy * ICR1;
xxx = xxx / 1023;
yyy = yyy / 1023;
//Assign values to OCR Registers, which output the PWM duty cycle.
OCR1A = int(xxx);
OCR1B = int(yyy);
}
Laatst gewijzigd door hepost op 05 Sep 2017, 20:56, in totaal 1 keer gewijzigd.

Berichten: 6
Geregistreerd: 01 Sep 2017, 20:58

Re: probleem met code voor motor driver

Berichtdoor hepost » 05 Sep 2017, 20:56

Bedankt voor de feedback Koepel!

Mijn kennis van elektronica en programmeren is nog niet zo groot. Ik heb wel wat klokken horen luiden maar ik weet niet altijd waar de klepels hangen.
Pin 14, 15 en 16 zal ik nog aanpassen naar A0, A1 en A2 in de sketch ;)

Met vriendelijke groet,
Hendrik Posthumus

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: probleem met code voor motor driver

Berichtdoor Koepel » 05 Sep 2017, 23:11

En ik dacht dat tegenwoordig alle treintjes een elektronische regeling in het het treintje zelf hadden :?

De code ziet er vreemd uit. Ik vraag me af of dat wel goed gaat om zomaar naar de registers van de timer te schrijven, terwijl de timer loopt. Maar misschien maakt het voor een treintje niet uit.

Wat voor treintje is het ? Loopt de stroom via de rails door de wielen ? Heeft het treintje een DC spanning nodig ?
Dus het PWM signaal knalt door alle draden, door de rails, naar de wielen en naar de motor, dat een inductieve belasting is ? Dat is geen ideale situatie.

Dan zou ik bijna gaan denken aan een filter (misschien een LC filter). Of misschien een motor-driver-module die dat al heeft. Misschien zelfs een motor-driver-module die niet de spanning regelt, maar de stroom. Sommige van die modules hebben een hoge interne PWM frequentie, bijvoorbeeld 100kHz of 1MHz.

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: probleem met code voor motor driver

Berichtdoor Koepel » 06 Sep 2017, 10:17

@hepost, ik hoop dat je dit nog leest. Ik bedacht me ineens dat ik voor motortjes gebruik heb gemaakt van: https://github.com/Palatis/arduino-softpwm.

Dat is een wat aparte benadering. Het laat een interrupt lopen en maakt daarmee een PWM signaal. Dus je kiest bij voorkeur een lage frequetie (jij hebt een lage frequentie) en een laag aantal PWM stappen (ik had er 30 om voldoende zachtjes de motor te starten).

Dan hoef je niet meer naar timer registers te schrijven.

Berichten: 6
Geregistreerd: 01 Sep 2017, 20:58

Re: probleem met code voor motor driver

Berichtdoor hepost » 06 Sep 2017, 21:10

Modern modelspoor is meestal digitaal. Er zit dan een decoder in het treintje en wordt aangestuurd met een digitaal signaal via de rails vanuit een centrale. Er zijn echter ook nog wel nieuwe analoge treintjes te koop. In mijn geval gaat het om een oud tweedehands analoog treintje. Het gaat om een tweerail baan, dus gelijkspanning. De stroom loopt via de wielen.

Softpwm, ga ik eens mee aan de slag.

Terug naar C code

Wie is er online?

Gebruikers in dit forum: Geen geregistreerde gebruikers en 2 gasten