BeneluxSpoor.net forum

Vraag en antwoord => Elektronica en analoog => Topic gestart door: hepost op 05 september 2017, 09:16:41

Titel: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: hepost op 05 september 2017, 09:16:41
Hallo,

Voor mijn analoog smalspoorbaantje heb ik een besturing gemaakt met een arduino nano, een H-brug bordje, aan-uit-aan schakelaar voor de rijrichting en een potmeter voor de snelheid. Bij mijn eerste poging kwam er geen beweging maar wel rook uit het treintje. Wat betreft elektronica en programmeren heb ik nog heel wat te leren. Na wat gepuzzel kwam ik erachter dat de frequentie te hoog was om het treintje op gang te helpen. Ik heb vervolgens de frequentie regelbaar gemaakt. Een frequentie tussen de 20 en 100 hertz lijkt goed te werken. Het rijgedrag is nog niet optimaal, de vraag is of het aan de aansturing ligt of aan het treintje zelf (een tweedehands liliput h0e treintje).

Een tweede vraag is wat ik kan doen om de boel te ontstoren. Ik heb een arduino asar besturing voor de servo's. Zodra het treintje begint te rijden gaan de servo's aardig tekeer. Ik heb wat gelezen over een condensator tussen de rails, draden wikkelen en zilverfolie om de draden van de servo. Wat is effectief? Wat voor condensator en hoe moet ik dit aansluiten? Dit heb ik nog niet kunnen vinden. In het treintje zit geen condensator o.i.d. Hoe kan ik er voor zorgen dat de motorregeling geen storingen op de servo's veroorzaakt?
Titel: Re: pwm met frequentieregeling met arduino t.b.v. besturing analoge dc treinbaan
Bericht door: hepost op 05 september 2017, 09:18:36
Hierbij de code voor mijn treinbesturing.

#include <Bounce2.h>

//Deze code werkt op een Arduino Uno/nano rev.3 met een L298n h-brug board.
//Hardware: 4 aan-uit-aan schakelaars, 3 potmeters
//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 = 14; //potmeter A
int P_SPEEDB = 15; //potmeter B
int freq = 16; //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);
}
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: Menno op 05 september 2017, 19:15:36
Bij mijn eerste poging kwam er geen beweging maar wel rook uit het treintje. Wat betreft elektronica en programmeren heb ik nog heel wat te leren. Na wat gepuzzel kwam ik erachter dat de frequentie te hoog was om het treintje op gang te helpen. Ik heb vervolgens de frequentie regelbaar gemaakt. Een frequentie tussen de 20 en 100 hertz lijkt goed te werken.
Dat is voor PWM-begrippen heel erg laag. In decoders wordt niet voor niets al jaren met 22 kiloHertz en (inmiddels) hoger gewerkt.
Wat wél kan: als je te lang hoogfrequente spanning op de baan zet met een te lage spanning om de motor aan te laten lopen, dan zal de motor wel opwarmen maar omdat die verder niet beweegt, wordt 'ie daar niet beter van. De truc van PWM is dat de spanning altijd maximaal is (bij een hele kleine dutycycle kan die zelfs nog hoger worden) maar dat je de dutycycle gaat variëren.
Een tweede vraag is wat ik kan doen om de boel te ontstoren. Ik heb een arduino asar besturing voor de servo's. Zodra het treintje begint te rijden gaan de servo's aardig tekeer. Ik heb wat gelezen over een condensator tussen de rails, draden wikkelen en zilverfolie om de draden van de servo. Wat is effectief? Wat voor condensator en hoe moet ik dit aansluiten? Dit heb ik nog niet kunnen vinden. In het treintje zit geen condensator o.i.d. Hoe kan ik er voor zorgen dat de motorregeling geen storingen op de servo's veroorzaakt?
Allereerst uitleggen hoe je de voeding regelt (los, uit 1 voeding?): bij dit soort zaken moet je hoge piekstromen gescheiden houden van stuurstromen, ook al delen die dezelfde massa. Zie het maar als een snelweg met een parallel-lopend fietspad: zowel auto's als fietsers kunnen dezelfde kant op, maar omdat de fietsers (de stuurstromen) zich ook vrijelijk op de snelweg kunnen begeven, gaat dat al snel mis.
Met een afgescheiden fietspad, is het probleem opgelost en kunnen zowel auto's als fietsers nog steeds dezelfde kant op.

Dat zal je ook moeten doen: scheid de voedingsspanningen zo snel mogelijk zodat de servo's zo min mogelijk meekrijgen van andere zaken. Ontkoppelen heet dat. Daarnaast kan een condensator hier en daar vaak niet zoveel kwaad om te proberen.
Draden van servo's en railspanning twisten is ook altijd een goed idee.

Nog mooier is een scoop: dan kan je kijken of je storing puur hardwarematig is (en veroorzaakt wordt door een rijdende trein) of dat de programmatuur rammelt, maar daar heb ik te weinig verstand van bij Arduino's.
Sowieso zie ik in die code (waarvan het fijn zou zijn als je het te lange commentaar even inkort) 4 schakelaars staan: ik weet dus niet wat er op een Arduino Uno of Nano gebeurt met ingangen die niet aangesloten zijn. Digitale ingangen die geen gedefiniëerd niveau hebben omdat ze niet aangesloten zijn maar wél aangeroepen worden als zijnde een ingang, moeten vaak een status krijgen om duidelijk te maken (voor de software) wat het niveau is. Dat kan dus betekenen dat je de ingang aan massa of voedingsspanning moet leggen (maar let op: zoek dat uit, ik heb geen idee hoe Atmel dat oplost (Atmel = fabrikant van de microcontrollers op Arduino's)
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: Klaas Zondervan op 05 september 2017, 19:44:12
Dat is voor PWM-begrippen heel erg laag. In decoders wordt niet voor niets al jaren met 22 kiloHertz en (inmiddels) hoger gewerkt.
In de analoge wereld is een lage frequentie heel gewoon. De befaamde Weistra regelaar werkt met een frequentie tussen 30 en 100 Hz, variërend met de duty cycle. Die hele hoge frequenties in het kilohertz bereik werken alleen maar goed in combinatie met lastregeling.
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: David Hoogvorst op 05 september 2017, 19:46:06
Standaard zet je voor 'zwevende' ingangen, die dus een losse draad kunnen hebben, de pinMode op INPUT_PULLUP.
De waarde die je dan uitleest is HIGH.

Als je de schakelaar sluit, moet deze aan aarde worden verbonden, dus niet aan de 5V, maar aan GND.
De waarde die je dan uitleest is LOW.

De logica is dan:
waarde HIGH: schakelaar is uit
waarde LOW: schakelaar is aan

Dit alles om te voorkomen dat je willekeurige waarden uitleest omdat de zwevende draad als antenne werkt.
De elektronica voor dit Pull up-gedrag is in de Arduino ingebouwd, je hoeft verder niets te doen.

Succes!
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: Timo op 05 september 2017, 21:23:51
Voor PWM zou hoog prima moeten werken. Nouwja, prima als in "geen rook" :angel: Maar zeker op lage snelheden is een loc niet echt willend om weg te rijden, zeker oude motoren niet. Vandaar dat ik toen ik een analoge regeling had gemaakt met een microcontroller 30kHz hardware PWM en daar dan 80Hz software PWM (met lage duty) bovenop. Dat laatste overkwam de "motorkleef" waarna de 30kHz de loc prima kon regelen.

En voor voeding en klapperende servo's, de boel inderdaad ontkoppelen etc. Anders even een schema plaatsen van hoe je alles hebt aangesloten nu.


Timo
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: hepost op 05 september 2017, 22:41:30
Hierbij het huidige schema. De voeding voor de baan is een gestabiliseerde 12v netvoeding van 2A (geaard). De voeding voor de arduino's is een 9v netadapter, 2A. De voeding voor de servo's is een gestabiliseerde netvoeding van 5v, max. 10A (geaard). Er zijn 2 arduino Nano's, een voor de asar servobesturing en een voor de rijregelaar.

De aan-uit-aan schakelaars werken goed, geen storing op de rijrichting. Wat ik echter begrijp van David is dat het toch verstandiger is om de weerstanden verwijderen van de schakelaars, rechtstreeks aan de arduino aansluiten en in de code de pinMode op INPUT_PULLUP zetten voor de desbetreffende pinnen.

Voor de asar servobesturing weet ik niet zeker of hier ook sprake is van zwevende ingangen. Het werkt met drukknoppen en een weerstandsladder.

Het is inderdaad mijn bedoeling om een soort Weistra regelaar te maken met behulp van een Arduino. Mijn idee is om de frequentie op te laten lopen tijdens het vermeerderen van de snelheid. Eerst een snelheidspuls om de kleef te overwinnen lijkt ook te helpen. Hoe ik dit allemaal nog in mijn code moet verwerken weet ik nog niet. Of ik iets met lastregeling kan/moet doen is mij ook nog niet duidelijk. Eerst maar eens wat meer te weten komen over dat onderwerp.

Hierbij het schema voor mijn rijregelaar. In het schema heb ik een Uno bord geplaatst maar ik maak gebruik van een nano. Ook het motorbord komt niet helemaal overeen maar de aansluitingen zijn praktisch hetzelfde.

(https://images.beneluxspoor.net/bnls/snelheidsregelaar.jpg) (https://images.beneluxspoor.net/bnls/snelheidsregelaar.jpg)

Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: Klaas Zondervan op 05 september 2017, 23:24:06
Vandaar dat ik toen ik een analoge regeling had gemaakt met een microcontroller 30kHz hardware PWM en daar dan 80Hz software PWM (met lage duty) bovenop. Dat laatste overkwam de "motorkleef" waarna de 30kHz de loc prima kon regelen.
Precies, je moet met een lage frequentie beginnen om de motorkleef te overwinnen. Een decoder met lastregeling doet dat door in eerste instantie "volle bak" te gaan en direct in te binden zodra hij constateert dat de motor draait.
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: David Hoogvorst op 06 september 2017, 09:54:30
Over de schakelaars: dit is niet per se verstandiger, maar wel veel eenvoudiger. Het scheelt 4 draden en weerstanden.
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: Timo op 06 september 2017, 19:44:17
@Klaas Zondervan, inderdaad :)

@David Hoogvorst, wat bedoel je met "niet verstandig"?


Timo
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: David Hoogvorst op 07 september 2017, 09:15:20
@Timo: 'hepost' suggereerde dat mijn suggestie 'verstandiger' zou zijn. Ik bedoelde te zeggen dat het niet verstandiger is, maar wel eenvoudiger om het Pull up mechanisme van de Arduino te gebruiken, omdat dit bedrading en weerstanden scheelt.
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: Hansepansje op 07 september 2017, 11:40:39
Als we toch gaan vereenvoudigen qua hardware: laat dan ook de aparte potmeter voor de frequentie vervallen.
In plaats hiervan: regel softwarematig (voor A en B apart) dat (net als bij de Weistra regelaar) de frequentie aangepast wordt aan de ingestelde snelheid. Dan krijg je ook een beter rijgedrag.

Groets, Hans
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: Klaas Zondervan op 07 september 2017, 13:24:44
En gewoon de Weistra regelaar nabouwen, is dat een optie? Of zeg ik nou iets heel raars?  ;D
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: 72sonett op 07 september 2017, 13:56:03
Of een  kant-en-klare kopen (https://nl.aliexpress.com/item/Free-Shipping-Mini-DC-Motor-PWM-Speed-Controller-3V-6V-12V-24V-35VDC-90W-DC-Motor/32634486563.html?spm=a2g0z.search0104.3.34.ONNj5Q&ws_ab_test=searchweb0_0,searchweb201602_2_10152_10065_10151_10068_5430020_5410020_10304_10307_10137_10060_10155_10154_10333_10334_10056_10335_10055_10054_10059_10332_100031_10099_5400020_10103_10102_10052_10053_10107_10050_10142_10051_10325_10326_10084_10083_5370020_10080_10082_10081_10177_10110_10111_5420020_10112_5390011_10113_10114_10312_10313_10314_10315_10078_10079_10210_10073-normal#cfs,searchweb201603_1,ppcSwitch_3&btsid=d5680257-54f1-4275-a373-2fa8d8f3b78e&algo_expid=e399711d-980c-42f7-8b4d-cd77b4da23f4-4&algo_pvid=e399711d-980c-42f7-8b4d-cd77b4da23f4&transAbTest=ae803_3) bij Aliexpress. Voor dat geld kun je ze niet zelf maken.

(https://ae01.alicdn.com/kf/HTB17uNpMXXXXXXNXFXXq6xXFXXXO/Gratis-Verzending-Mini-DC-Motor-PWM-Controller-3-V-6-V-12-V-24-V-35VDC.jpg)
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: Klaas Zondervan op 07 september 2017, 14:30:11
Dat is een ding wat op 10 kHz draait. Dus heel wat anders dan een Weistra regelaar.
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: nkob op 07 september 2017, 15:29:34
lijkt samen te lopen met mn draadje over pulsbreedte
Inmiddels niet veel opgeschoten
Komt ook door mn IPadres
Een prettig gesprek gehad met wentinkhobby in arnhem
Had wel van pulsbreedte gehoord maar gaf aan dat bijna iedereen digitaal rijdt
gaugemaster klonk bekend en heisswolf ook .
Afgesproken om langs te komen en verder te praten .
Hopelijk kom ik dan verder .
groet
kees

Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: Klaas Zondervan op 07 september 2017, 15:40:39
Had wel van pulsbreedte gehoord maar gaf aan dat bijna iedereen digitaal rijdt
Weet hij dan wel dat digitaal uitsluitend met pulsbreedtesturing werkt?
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: nkob op 07 september 2017, 16:11:17
ik denk het wel klaas
Verbinding was slecht maar gaf aan dat hij die, regelaars ,niet heeft .
Een diepgaand gesprek komt wel als ik er ben .
Ben daar al eerder geweest en vond het een mooie zaak .
Een persoonlijk gesprek is altijd beter dan mailen of bellen ,vind ik tenminste .
groet kees

Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: 72sonett op 07 september 2017, 16:13:10
Citaat van: Klaas Zondervan
Dat is een ding wat op 10 kHz draait. Dus heel wat anders dan een Weistra regelaar.
Anders ja, maar het principe van PWM is hetzelfde.

De TS wil met die Arduino behalve PWM ook servo's aansturen, dat kan met dit ding niet  (met de Weistra regelaar ook niet). Daar zijn dan weer extra servoregelaars (https://nl.aliexpress.com/item/Servo-Tester-3CH-ESC-4-8-6V-CCPM-Servo-Master-Checker-Multi/32286090920.html?spm=a2g0z.search0104.3.9.qW5boE&ws_ab_test=searchweb0_0,searchweb201602_2_10152_10065_10151_10068_10304_10307_10137_10060_10155_10154_10056_10055_10054_5470020_10059_100031_10099_5460020_10103_10102_10052_10053_10142_10107_10050_10051_10325_5380020_10326_10084_10083_10080_10082_10081_10177_10110_10111_10112_10113_10114_143_10312_10313_10314_10078_10079_10210_10073-10102,searchweb201603_18,ppcSwitch_3&btsid=7613336f-2373-476e-b6cf-10e412fe9ff8&algo_expid=d1525034-ff0b-499d-9884-5ed23e45b746-1&algo_pvid=d1525034-ff0b-499d-9884-5ed23e45b746) voor nodig (ook PWM overigens).

(https://ae01.alicdn.com/kf/HTB1SZ8rRpXXXXcOapXXq6xXFXXXE.jpg)
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: Klaas Zondervan op 07 september 2017, 16:49:24
Anders ja, maar het principe van PWM is hetzelfde.
Dat wel, maar de frequentie is toch wel een punt. 10kHz is gewoon veel te hoog als je analoog rijdt.
Het bijzondere van de Weistra regelaar is dat die met een lage frequentie begint, en die loopt op met de duty cycle.
Het is overigens een herhaling van zetten, want dat is in dit draadje allemaal al aan de orde geweest.
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: Timo op 09 september 2017, 19:04:04
Zodra de boel in beweging is, dan is de 10kHz prima. Maar voor het wegrijden is dat inderdaad wat lastiger. Dat doet de Weistra regelaar mooi. En iets soortgelijks kan je ook redelijk simpel doen met een Arduino. Eventueel zou ik een soort voorbeeld of library kunnen maken als er interesse in is. :) Je zou zelfs de Weistra echt kunnen nabootsen met een Arduino. 8) Maar ik heb geen Weistra-regelaar (zelfs op dit moment geen werkplaats überhaupt) dus kan de karakteristieken niet nameten.


Timo
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: Klaas Zondervan op 09 september 2017, 20:05:10
Je hoeft de Weistra regelaar niet na te meten. Het principe is in het kort dit: bij een lage duty-cycle is de frequentie 30 Hz. Met het toenemen van de duty-cycle neemt ook de frequentie toe, tot 100Hz bij 100% duty-cycle.

Het enige schoonheidsfoutje is dat de regeling niet lineair is, dus 50% potmeterverdraaiing levert niet 50% snelheid op. Maar dat is nou net een puntje wat je met een namaak in software recht kan zetten.
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: Timo op 09 september 2017, 20:39:48
Is de frequentie wel lineair met de snelheid dan? Of juist met de potmeter? Dat is me dus vooral iets wat ik me afvraag :) Als het lineair met de snelheid is, dan is het een eitje om het na te maken in software.


Timo
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: Klaas Zondervan op 09 september 2017, 20:57:53
Ik heb nooit gemeten hoe de frequentie varieert met de potmeterstand of met de snelheid.
Maar ik neem aan dat de snelheid evenredig is met de duty-cycle. Of de frequentie precies lineair verloopt is volgens mij minder interessant. De belangrijkste reden om met een lage frequentie te beginnen is om ervoor te zorgen dat je al bij een lage duty-cycle pulsen krijgt die lang genoeg zijn om het anker over de kleef heen te helpen.
Ik kan e.e.a wel eens nader onderzoeken. Maar dit weekend zal dat niet lukken.
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: Timo op 10 september 2017, 10:58:30
Dank je Klaas. Dat het niet zo nauw komt kan best maar als je de Weistra in software wilt doen moet je het wel echt doen. Mijn andere methode van 30kHz boven op 80Hz werkte namelijk ook prima maar iedereen vind de Weistra altijd zo geweldig werken dus is het eens leuk ze beide in software te hebben zodat je kunt testen. :)


Timo
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: hepost op 10 september 2017, 16:41:41
De frequentie koppelen aan de snelheid had ik al in gedachten. Ik regel de frequentie nu eerst handmatig om een idee te krijgen hoe lang de frequentie laag moet blijven om het treintje op gang te krijgen. Ik kan mij voorstellen dat dit per trein verschillend is. Het brommen van het motortje wordt hoger als de frequentie hoger wordt. Ik laat nu de frequentie laag, ook bij hogere snelheden omdat ik dit een prettiger geluid vind. De frequentie laten oplopen naar een niet hoorbare frequentie kan ook maar heb ik nog niet geprobeerd. Of die hoge frequentie kwaad kan voor de motor weet ik niet.

Ik vind het geweldig als iemand een Weistra regelaar met een Arduino kan en wil maken. Ik zal daar dan ook dankbaar gebruik van willen maken. Ik blijf ondertussen zelf ook wel wat door modderen, al doende leert men.

Voor het ontstoren heb ik hier en daar wat gelezen, onder andere een condensator van 1uF tussen de rails. Nu kan ik verschillende condensatoren vinden waaronder ontstoringscondensatoren, kan ik die gebruiken of maakt het niet zoveel uit wat voor type condensator het is?
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: Timo op 10 september 2017, 17:04:43
Hoge frequentie is prima voor een motor. Faulhaber / cordless motoren worden juist blijer van hoger frequenties.

En juist geen condensator tussen de rails plaatsen, daar wordt niets blij van ;)


Timo
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: hepost op 11 september 2017, 22:35:46
Ok, geen condensator tussen de rails dan. Op het Belgische forum had iemand een 100nf keramische condensator over de aansluitingen van de motor in de loc geplaatst. Dit om het spontane bewegen van servo's te verhelpen zodra de trein voorbij kwam. He lijkt mij wel iets om uit te proberen of is dit niet aan te raden?

Wat betreft de snelheidsregelaar ben ik wat aan het experimenteren geweest. De frequentie heb ik nu van 20 herz tot 31250 herz regelbaar gemaakt. Om het treintje op gang te brengen hoef ik maar even de 20 herz te gebruiken, daarna kan ik de hoge frequenties gebruiken. Met de hogere frequenties lijkt het treintje wel langzamer en soepeler te kunnen rijden. Soms lukt het ook om het treintje direct met de hoge frequentie op gang te brengen maar niet altijd. Ik denk dat de drijfstangen iets scheef zijn en dus weerstand veroorzaken omdat het treintje wat bokkig rijdt, ook als ik een gewone treintrafo gebruik.

Nu wil ik het zo maken dat vanaf snelheid nul eerst een korte periode van 20 hz wordt toegepast, daarna wordt overgeschakeld naar ca. 32khz totdat de snelheid weer nul is. Ik zit nog met hoe ik dit moet regelen als de rijrichting ineens wordt omgezet terwijl de snelheidsregelaar niet op nul staat. Ik denk dat de snelheid dan eerst naar nul moet lopen en dan weer naar de ingestelde waarde van de snelheidsregelaar. Nog iets om over na te denken.

Is er een beveiliging dat de regelaar naar nul brengt om te voorkomen dat het motortje te heet wordt als de motor stil valt? Een soort van terugkoppeling van de motor dus.

Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: Timo op 12 september 2017, 20:55:52
Ok, geen condensator tussen de rails dan. Op het Belgische forum had iemand een 100nf keramische condensator over de aansluitingen van de motor in de loc geplaatst. Dit om het spontane bewegen van servo's te verhelpen zodra de trein voorbij kwam. He lijkt mij wel iets om uit te proberen of is dit niet aan te raden?
Kan wat helpen maar kan het met PWM ook erger maken. Het is dan vaak makkelijker om juist de spanning naar de servo te ontstoren :) En 100nF is nog steeds iets heeeeeel anders dan de 1uF ;)

Wat betreft de snelheidsregelaar ben ik wat aan het experimenteren geweest. [knip]
Die lage freqentie (jij hebt 20Hz, ik deed 80Hz) kan je ook prima in software boven op de 32kHz hardware PWM doen. Maakt het allemaal makkelijker.

Ik zit nog met hoe ik dit moet regelen als de rijrichting ineens wordt omgezet terwijl de snelheidsregelaar niet op nul staat. Ik denk dat de snelheid dan eerst naar nul moet lopen en dan weer naar de ingestelde waarde van de snelheidsregelaar. Nog iets om over na te denken.
Je kunt het zo gek maken als je wilt. Maar op een analoge trafo zit hier ook geen beveiliging voor ;)

Is er een beveiliging dat de regelaar naar nul brengt om te voorkomen dat het motortje te heet wordt als de motor stil valt? Een soort van terugkoppeling van de motor dus.
Misschien, maar niet makkelijk of in ieder geval niet makkelijk universeel. Daarom hielt ik de 80Hz PWM met +-9% duty cycle altijd staan :) En daar boven op de duty cycle van de hardware (32kHz) PWM regelen. Zeg niet dat het zalig makend is maar leek prima te werken  :)


Timo
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: hepost op 12 september 2017, 22:23:35
Citaat
En 100nF is nog steeds iets heeeeeel anders dan de 1uF
Die waarde kwam weer van een ander forum. Ik heb er weinig kaas van gegeten zoals je wel begrijpt. Kan het kwaad als ik het probeer?

Citaat
Daarom hielt ik de 80Hz PWM met +-9% duty cycle altijd staan  En daar boven op de duty cycle van de hardware (32kHz) PWM regelen.
Ik heb nu een sketch met een aparte pin met softwarematige pwm op 20Hz. Die ga ik aansluiten op de H-brug. Morgen testen, kijken of ik het werkend kan krijgen.
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: Klaas Zondervan op 14 september 2017, 14:21:48
Voor wie er nog interesse in heeft hier de grafieken die ik heb opgenomen van de Weistra regelaar.

De eerste grafiek geeft het verband tussen de potmeterstand enerzijds en de pulsfrequentie en duty-cycle anderzijds.

(https://images.beneluxspoor.net/bnls/puls-duty.gif) (https://images.beneluxspoor.net/bnls/puls-duty.gif)

De tweede grafiek geeft het verband tussen potmeterstand en baanspanning/snelheid.

(https://images.beneluxspoor.net/bnls/spanning-snelheid.gif) (https://images.beneluxspoor.net/bnls/spanning-snelheid.gif)

Wat opvalt is dat de frequentie redelijk lineair verloopt. De grafiek van de duty-cycle is enigszins hol, terwijl baanspanning en snelheid juist bol verlopen. Strikt genomen klopt dat niet, duty-cycle en baanspanning zouden theoretisch dezelfde vorm moeten hebben.
In de eerste 20% van de potmeter gebeurt er niks terwijl boven 70% de snelheid aardig uit de hand loopt. Ik overweeg dan ook om aan de onderkant en de bovenkant van de potmeter vaste weerstanden toe te voegen, zodat de potmeter zelf alleen het bereik tussen 20 en 70% bestrijkt.

De snelheidsproef is gedaan met een Roco TEE treinstel dat is omgebouwd naar analoog (af fabriek zit er standaard een decoder in).
Verder is het treinstel voorzien van andere wormsets. Waar het eerst een slak was is het nu een racemonster geworden.
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: Timo op 15 september 2017, 09:39:08
Hoi Klaas,

Interessante meting :) Frequentie is inderdaad aardig lineair met de potmeter maar de duty iets minder. Maar denk dat een lineaire interpretatie wel goed te maken is. Maar liever zou je natuurlijk de boel lineair maken met de snelheid of baanspanning. Hoe heb je dat laatste gemeten? Gemiddelde of RMS?


Timo
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: Klaas Zondervan op 15 september 2017, 09:42:22
De baanspanning heb ik gemeten op het gelijkspanningsbereik. Dan meet je vanzelf de gemiddelde waarde.
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: Hansepansje op 03 oktober 2017, 17:56:01
Leuk topic!
Omdat ik zowel treintjes als Arduino's leuk vind, ben ik maar eens begonnen om te kijken of ik een 'Weistrarduino regelaar' kan maken.

Inmiddels ben ik op een proefbordje met Arduino, potmeter, L293D, motortje en LCD display zover dat ik de motor heen en weer kan laten draaien o.b.v. de stand van de potmeter, en wat info op het display tonen.
Nu ben ik aan het kijken of ik de PWM frequentie van de Arduino aangepast kan krijgen. Als dat ook lukt, dan liggen de ingredienten voor de 'Weistrarduino regelaar' voor het oprapen om er wat leuks van te bakken.  ::)

Groets, Hans
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: Timo op 03 oktober 2017, 21:58:37
De frequenties van de Weistra regelaar zijn erg laag. Ook is deze steeds iets anders per stand. De hardware PWM is dan alleen maar lastig. Denk dat je naar software PWM moet en deze maken op basis van een timer interrupt. Verder alleen geen tijd gehad dit verder uit te werken... ::)


Timo
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: Hansepansje op 04 oktober 2017, 08:15:24
Timo,

De frequentie van de 'standaard PWM' is inderdaad te hoog. Maar de frequentie en duty cycle van een timer is softwarematig aangepast.
Gisteravond een eerste poging gedaan en er zit schot in: Het aangesloten testmotortje komt in beweging, nog beter zelfs als de startfrequentie bij lage duty cycle onder de 30 Hz zakt, bijv 15 Hz.
Nu dit in de basis lijkt te werken, wil ik verdergaan en er een lokmotortje op aansluiten. Ik heb ook een Weistra regelaar, dus indien nodig kan ik mooi vergelijken. Alleen heb ik geen scope, dus precies meten van frequenties en duty cycles gaat lastig worden.

Wordt vervolgd.

Groets, Hans
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: Timo op 04 oktober 2017, 11:05:52
Je kan het inderdaad wijzigen. Maar niet onafhankelijk ;) De PWM frequentie kan je maar instellen op een paar waardes met behoudt van de volle range voor de duty cycle. Bij benadering zijn dat 30Hz, 60Hz, 122Hz, 244Hz, 490Hz, 980Hz, 3,9kHz, 7,8kHz, 31kHz en 62kHz. Alle andere frequenties beïnvloed de resolutie van de duty cycle.


Timo
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: Hansepansje op 04 oktober 2017, 17:31:05
Ja Timo, dat heb ik gezien, maar me bij de eerste pogingen niet teveel in verdiept. Ga ik zeker nog doen.
Even kort door de bocht: Als ik van 30 Hz met 255 stappen 'terug' ga naar 90 Hz, dan zou ik nog zo'n 85 stappen overhouden. Of misschien zelfs van 511 stappen terug naar 170. Dat lijkt me een voldoende range om daarmee de duty cycle nog genuanceerd te kunnen regelen.

Groets, Hans
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: Timo op 04 oktober 2017, 22:12:59
85 stappen is niet zo veel voor gladde overgangen en als je de verschillen tussen de stappen een beetje gelijk wilt hebben. En bedenk dat je vaak niet tot 100% duty wilt omdat het anders een TGV is.

Maar lastiger is het rekenwerk om steeds de juiste duty en freqenctie te bepalen. Toegegeven, dit kan in een lookup. Maar ik denk dat je een vloeiendere lijn krijgt als je zelf aan de slag gaat met een timer :)


Timo
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: Hansepansje op 20 oktober 2017, 11:45:19
Een eerste versie is gelukt! Zie hier (https://youtu.be/IvWvclXoUDM)  8)
(M'n excuses voor de matige beeldkwaliteit van het filmpje)

Benodigdheden voor deze pilot zijn minimaal: 12 volt voeding, Arduino, L293D regelaar, wat draadjes en voor de liefhebbers die 'binnenin' willen kijken een LCD display.
Op het filmpje is te zien dat de loksnelheid mooi te regelen is. De hierbij gebruikte instellingen zijn als volgt:
- frequentie bereik: 30-100 Hz
- duty cycle bereik: 0-75%
- aantal stappen: 64

Het idee achter deze pilot (net als bij de Weistra regelaar): de stand van de potmeter wordt (in beginsel zo lineair mogelijk) omgezet in frequentie en duty cycle van het Arduino PWM signaal.
Het rekenwerk voor de omzettingen (van potmeterstand naar frequency/duty cycle naar timer trigger levels valt reuze mee.
Maar om snel wat waarden in te kunnen stellen/veranderen (nulstand potmeter, start/stop waarde van frequentie en max. duty cycle gebruik ik een paar hashing tabellen. Om bij het programmeren me niet te verslikken in alle getalletjes op een rij, heb ik een spreadsheet gemaakt. Hiervandaan kan ik de definities van de verschillende hashing tabellen zo in de code kopieren.

Als toelichting op wat je op het filmpje ziet, op het LCD display:
  162[10] 193/21
  41Hz, 12%
dan betekent dit:
  162: ingelezen stand van de potmeter [bereik: 0-1023]
  [10]: hieruit afgeleide stap [bereik: 0-64]
  193: bovenste timer trigger level (OCnA, bepaalt frequentie)
  21: onderste timer trigger level (OCnB, bepaalt samen met OCnA de duty cycle)
  41Hz: frequentie van PWM signaal
  12%: duty cycle van PWM signaal

Vanuit stilstand heel langzaam optrekken en vloeiend versnellen lijkt hiermee prima mogelijk.
Binnenkort de boel maar eens aansluiten op een railovaal, zodat het rijgedrag over de hele range goed te bestuderen is. De eerste indruk op een stuk flexrail is in ieder geval bemoedigend.  ::)

Groets, Hans
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: Daan Neijenhuis op 20 oktober 2017, 12:11:21
Cool !   (y)
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: dickkoning op 20 oktober 2017, 12:31:02
Leuk gedaan
Kun je een schema en je code eens posten
Dick
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: hepost op 20 oktober 2017, 15:38:35
Mooi! Die trein kruipt echt weg. Ik ben benieuwd of het voor mijn treintje ook zo goed zal werken.
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: Hansepansje op 21 oktober 2017, 20:27:33
Op verzoek, hierbij wat meer info van m'n pilot.

Het schema ziet er als volgt uit:
(https://images.beneluxspoor.net/bnls/PWM-schema.jpg) (https://images.beneluxspoor.net/bnls/PWM-schema.jpg)

De motorspanning die op pen 8 van de L293D wordt aangeboden heb ik afgetakt van de inkomende externe voeding van de Arduino, die ik voor deze pilot op 12 volt heb aangesloten.

De code voor de Arduino is als volgt:
// PWM-test-2
// Translate potmeter position into frequence and duty cycle of PWM signal

/*-----( Import needed libraries )-----*/
#include <Wire.h>  // Comes with Arduino IDE
#include <LCD.h>
// Get the LCD I2C Library here: https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads
#include <LiquidCrystal_I2C.h>
// set the LCD address to 0x27 for a 16 chars 2 line display
// Set the pins on the I2C chip used for LCD connections:
//                    addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address

/*-----( Define constants and variables )------*/
unsigned long pwm1;        // Value read from A03 to give PWM duty cycle output in terms // of 0-5V
unsigned long potMeter;

const byte pinPotmeter = 3;
const byte pinMotor1    = 4;
const byte pinMotor2    = 5;
const byte pinTimer2a  = 3;
const byte pinTimer2b  = 11;
const byte MaxStep      = 64;
int potmeterLimits[] = {10, 26, 42, 57, 73, 89, 105, 121, 137, 152, 168, 184, 200, 216, 232, 247, 263,
279, 295, 311, 327, 342, 358, 374, 390, 406, 422, 437, 453, 469, 485, 501, 517, 532, 548, 564, 580,
596, 611, 627, 643, 659, 675, 691, 706, 722, 738, 754, 770, 786, 801, 817, 833, 849, 865, 881, 896,
912, 928, 944, 960, 976, 991, 1007, 1023};
// For display purpose only, required values for PWM Frequency and Duty Cycle.
int Freq_Hashing[] = {31, 31, 32, 33, 34, 35, 36, 37, 38, 39, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 52,
53, 54, 55, 56, 57, 58, 59, 60, 61, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 74, 75, 76, 77, 78, 79, 80, 81,
82, 83, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96, 97, 98, 99, 100};
int DC_Hashing[] = {0, 1, 2, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 22, 23, 25, 26, 27,
28, 29, 30, 32, 33, 34, 35, 36, 38, 39, 40, 41, 42, 43, 45, 46, 47, 48, 49, 50, 52, 53, 54, 55, 56, 57, 59,
60, 61, 62, 63, 64, 66, 67, 68, 69, 70, 71, 73, 74, 75};
// Values for OCnA and OCnB, calculated from PWM Frequency and Duty Cycle.
int OCnA_Hashing[] = {255, 255, 247, 238, 231, 223, 217, 210, 204, 199, 193, 188, 183, 179, 174, 170,
166, 162, 159, 155, 152, 149, 146, 143, 140, 137, 135, 132, 130, 128, 125, 123, 121, 119, 117, 115, 113,
112, 110, 108, 107, 105, 104, 102, 101, 99, 98, 97, 95, 94, 93, 92, 91, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, 79, 79};
int OCnB_Hashing[] = {0, 2, 4, 7, 9, 12, 14, 16, 18, 20, 21, 23, 24, 26, 27, 29, 30, 31, 32, 33, 34, 35, 36,
37, 38, 39, 40, 41, 41, 42, 43, 44, 44, 45, 46, 46, 47, 47, 48, 48, 49, 49, 50, 50, 51, 51, 52, 52, 53, 53, 54,
54, 55, 54, 55, 55, 56, 56, 56, 57, 57, 57, 57, 58, 59};

void setup()
{
  // Initialize motor pins
  pinMode(pinMotor1, OUTPUT);
  pinMode(pinMotor2, OUTPUT);

  // Set motor pins unequal to ensure movement controlled by enable
  digitalWrite(pinMotor1, HIGH);
  digitalWrite(pinMotor2, LOW);

  // Set timer 2 op phase-correct PWM with OCRA controlling top limit, prescaler 1024
  pinMode(pinTimer2a, OUTPUT);
  pinMode(pinTimer2b, OUTPUT);
  TCCR2A = _BV(COM2A0) | _BV(COM2B1) | _BV(WGM20);
  TCCR2B = _BV(WGM22)  | _BV(CS22)   | _BV(CS21) | _BV(CS20);  // Prescaler Value is 1024

  // Initialize lcd screen
  lcd.begin(16, 2);  // initialize the lcd for 16 chars 2 lines
  lcd.backlight();    // Turn backlight on
}

byte getPotmeterSetting()
{
  byte iCheck = 0;
  // Read potmeter value;
  potMeter = analogRead(pinPotmeter);

  // Determine matching index value and return it
  while ((potMeter > potmeterLimits[iCheck]) && (iCheck < MaxStep)) { iCheck++; }
  return iCheck;
}

void setTimer2(int iIndex)
{
  //Assign values to OCR Registers, which determine PWM frequency and duty cycle.
  OCR2A = OCnA_Hashing[iIndex];
  OCR2B = OCnB_Hashing[iIndex];

  // Display various variables on LCD screen
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(potMeter); lcd.print("["); lcd.print(iIndex); lcd.print("] ");
  lcd.print(OCnA_Hashing[iIndex]); lcd.print("/"); lcd.print(OCnB_Hashing[iIndex]);
  lcd.setCursor(0, 1);
  lcd.print(Freq_Hashing[iIndex]);
  lcd.print("Hz, "); lcd.print(DC_Hashing[iIndex]); lcd.print("%");
}

void loop()
{
  // Check potmeter value and set frequency and duty cycle accordingly
  setTimer2(getPotmeterSetting());
  // Wait half a second
  delay(500);
}

Vragen of opmerkingen zijn welkom.

Groets, Hans
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: 72sonett op 21 oktober 2017, 21:36:38
Kun je de dataregels in het codeblok korter maken, het past niet op het scherm.
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: Hansepansje op 21 oktober 2017, 21:50:10
Werkt scrollen niet op je scherm?
Ik heb wat returns tussengevoegd. Hopelijk helpt dat.

Groets, Hans
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: 72sonett op 21 oktober 2017, 22:04:30
Jawel, maar horizontaal scrollen is vervelend en onhandig.

Nu is het OK.
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: dickkoning op 21 oktober 2017, 23:10:02
Hi
Ziet er mooi uit
Ga ik proberen
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: Hansepansje op 23 oktober 2017, 12:59:45
Ik ben benieuwd naar jullie ervaringen!  ::)

Groets, Hans

PS
Mocht je de waarden van de hashingtabellen eenvoudig willen aanpassen m.b.v. de spreadsheet, stuur me dan even een berichtje met je email adres, dan kan ik die naar je toe mailen.
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: Timo op 11 november 2017, 21:58:47
Hoi Hans,

Leuk gedaan! :)

Paar opmerkingen over de (geen kritiek, maar mogelijke verbeteringen.

Die spreadsheets zou je makkelijk op Google drive kunnen zetten :)

Wat jij hashing tables noemt zijn geen hasing tables maar lookup tables ;)

DC_Hashing is natuurlijk beetje zinloos aangezien DC_Hashing[index] gewoon index is ;) Maar goed, valt wat voor te zeggen als je wel tot 100% wilt. Maar dan nog is het lineair dus nog makkelijk te doen voor de micro.

De PWM kan je beter op de enable zetten van de H-brug. Heb je maar één PWM pin nodig en maar één loopup etc. Doe je maar je gebruikt pin 11 gewoon niet :angel:

Goed dat je const gebruikt voor de pinnen, maar zou nog meer schelen voor de lookup tables. En nog meer als je ze in PROGMEM zet.

getPotmeterSetting() is nu beetje een omgekeerde loopup. Als je van 65 stappen naar 64 stappen gaat is het een stuk makkelijker ;)
getPotmeterSetting(){
  return analogRead(pinPotmeter) >> 4;
}

Gebruik als naam wat je er werkelijk mee doet, niet wat het op de Arduino voorstelt. Dus PinMotor1A ipv pinTimer2a. Lijkt erg op elkaar maar ik zie daardoor mensen ook dingen wel eens PwmPin11 noemen terwijl het de pin is die de verlichting stuurt. De namen zijn er om je te helpen en duidelijk te maken wat je doet.

Zelfde voor de functie namen. setTimer2 doet meer dan de naam doet vermoeden bijvoorbeeld. Splits het in SetTimer2() en updateLcd() bijvoorbeeld.

lcd.print("Hz, "); lcd.print(DC_Hashing[iIndex]); lcd.print("%");Hier gaan bij veel de nekharen overeind staan en maakt foutzoeken onnodig lastig. Niets volgt een ; ;) Het geeft het einde van de code in de regel aan. Uitzondering in een for-loop en commentaar.

Haal de delay() eruit. delay()'s maken het praktisch onmogelijk later meer tegelijk te doen met je programma en vertragen nu de response. Beter zou zijn om bijvoorbeeld alleen de timer een update te geven als de potmeter is verandert. En ook niet constant het hele scherm leeg te halen maar alleen het deel met waardes opnieuw te sturen.

Maak dingen alleen global als je het nodig hebt. potMeter (betere naam: potmeterValue) gebruik je alleen in getPotmeterSetting(). En pwm1 gebruik je nooit.

Probeer één stijl te hanteren. Voorbeelden, of { aan het eind van de regel of altijd op een nieuwe. Maar ook voor namen, nu gebruik je namenAlsDeze MaarOokDeze En_Deze. De meest geaccepteerde standaard binnen Arduino is ditVoorVariabele (/objecten), DitVoorConstVariable (of classes maar hebben dezelfde eigenschap dat je ze niet kunt wijzigen) en DIT_VOOR_MACROS (maar macros alleen gebruiken als er echt geen alternatief is).


Goed, lijkt heel negatief maar zo bedoel ik het niet! (y) Vind het juist leuk om andere bezig te zien met elektronica en microcontrollers. Maar ik probeer dan wel altijd tips te geven om het project te verbeteren of om betere/makkelijker/duidelijkere code te schrijven.
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: jmu op 20 november 2017, 11:01:28
Al zoekende naar een oplossing voor mijn probleem kwam ik op dit onderwerp. Ik zal eerst mijn opzet schetsen. Ik rijd met H0e materiaal van Egger, Bemo, Joueff en Roco en mijn baan betreft een (automatisch) pendelbaantje met een helling en stopplaats halverwege. Voor de aansturing maak ik gebruik van een Arduino Uno en een DFRobot motorshield L298P.

De problemen waartegen ik aanloop zijn:
Verschillende locs hebben verschillende snelheden
Per loc verschilt de snelheid voor- en achteruit
De motorkleef is lastig op te lossen

Ik heb geprobeerd om de PWM op een andere frequentie te zetten en dat levert weer andere rij eigenschappen op, maar het draait allemaal nog niet soepel. En bijkomend probleem: doordat de motorshield vast op poort 5 en 6 zit, verandert timer0 ook, dus ook alle bijbehorende timers.

Begrijp ik nu goed uit het bovenstaande dat de PWM frequentie aangepast wordt aan de snelheid? Zo ja, weten jullie of het mogelijk is om dit ook toe te passen op mijn motorshield? Dan zal ik wss de pinnen moeten verplaatsen, of anders aansluiten.

Nog een vraag over de motoren van de locjes: hier zit vaak een kleine spoel en condensator op. Hebben deze invloed op de rei eigenschappen als je een PWM signaal gebruikt?

Joop
 
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: Timo op 20 november 2017, 21:04:34
Hoi JMU,

Deze software past ook de timer aan dus timer0 is nog steeds niet te gebruiken.

En in dit geval wordt de frequentie inderdaad geschaald met de snelheid. Dat is wat de originele Weistra regelaar ook deed en om die te imiteren was hier het doel. Of dat het absoluut beste rijgedrag geeft, geen idee, dat zou je moeten proberen. Maar het gaat niet magisch het verschil in snelheid tussen locs oplossen. Ook analoog zit er veel snelheidsverschil tussen loc's.

Je zou natuurlijk gewoon de motor driver naar een ander PWM pin kunnen doorlussen. En als je de oorspronkelijke pin (pin 5 of 6) gewoon als input laat hoef je deze niet los te koppelen.

Andere oplossing is om niet de hardware PWM te gebruiken. De frequenties van een Weistra regelaar zijn laag genoeg dat je deze met software PWM (bitbang PWM) kan doen. Gebruik alleen geen delay() (moet je überhaupt nooit doen ;D)  maar doe het op basis van millis().

Zelf heb ik in het verleden een combinatie gebruikt. Ik gebruikte de hardware PWM voor het regelen en deze stond ook redelijk snel (+-30kHz). Maar naast dat gebruikte ik een lage (+-80Hz) software PWM er overheen om de kleef te overwinnen. Beste van twee werelden zeg maar ;D


Timo
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: jmu op 21 november 2017, 10:21:51
Dag Timo,

Bedankt voor je uitleg. Je stelt dat timer0 aangepast wordt; dat betekent toch ook dat tijdfuncties als millis() niet meer correct zijn?
Het nadeel van een shield is dat de uitgangen min of meer vast liggen. Ik zit dus vast aan D5 en D6 en die zitten weer vast aan timer0. Volgens mij kan ik daar weinig aan doen, of ik moet het shield gaan aanpassen (of met draadjes gaan aansluiten).
Een oplossing zou kunnen zijn dat ik timer1 ga gebruiken voor de tijd-gerelateerde functies, daar moet ik nog even induiken, want daar weet ik te weinig van.

Jij hebt het over een softwarematige PWM oplossing. Kan je mij daar iets meer over vertellen? Ik ga er van uit dat de Arduino een PWM signaal genereert op poorten 5 en 6 en dat dit signaal door de shield wordt gebruikt (versterkt) om de lok aan te sturen. Dat PWM signaal van de Arduino is dan toch al een softwarematige oplossing, of zie ik dat verkeerd?

Joop
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: Timo op 21 november 2017, 21:23:48
Bedankt voor je uitleg. Je stelt dat timer0 aangepast wordt; dat betekent toch ook dat tijdfuncties als millis() niet meer correct zijn?
Nouwja, het principe wat hier gedaan wordt gebruikt een timer. Alleen wordt hier timer2 gebruikt (vandaar pin 3 en pin 11) en deze doet niets met de timing van millis() en aanverwante. Zelfde zou je ook gewoon op timer1 kunnen toepassen maar niet op timer0 voor pin 5 en 6.

Het nadeel van een shield is dat de uitgangen min of meer vast liggen. [knip] of met draadjes gaan aansluiten.
Nouw, dat! ;D Gewoon een draadje van pin 3 naar pin 5 en van pin 11 naar pin 6 en je bent klaar ;)

Een oplossing zou kunnen zijn dat ik timer1 ga gebruiken voor de tijd-gerelateerde functies, daar moet ik nog even induiken, want daar weet ik te weinig van.
Dat is dan ook niet zo makkelijk. Dan moet je een groot deel van de Arduino core gaan aanpassen. Niet onmogelijk, maar twee draadjes is wel enkele uren sneller ;D

Jij hebt het over een softwarematige PWM oplossing. Kan je mij daar iets meer over vertellen?
PWM is niets meer als het snel aan en uit zetten van een uitgang. En hoe groter deel van de tijd aan hoe sneller/feller. Dat is de duty cycle. De PWM pinnen van de Arduino kunnen dit in hardware. Dat wil zeggen, je stelt het in en daarna hoeft de code niets te doen om een bepaalde duty cycle te houden.

Maar als je kijkt naar blink Sketch is dat eignelijk ook PWM maar dan traag en in software. Maar je zou prima de tijden aan kunnen passen naar 3ms en 7ms en dan lijkt het voor jou gewoon dat je een ledje dimt ipv laat knipperen. Maar goed, dat wil je niet met delay() doen want dan kan je niets anders doen. Maar dat kan je ook met millis() doen. Zie daarvoor blink without delay.

Dat PWM signaal van de Arduino is dan toch al een softwarematige oplossing, of zie ik dat verkeerd?
Bij de hardware PWM pinnen is het dus set-and-forget (blijft ook door gaan ook al zou je delay(10000000) doen. Terwijl je met software PWM continue voor de juiste staat van de pin moet zorgen (en dus met de juiste timing). Nu is dat met maximaal 100Hz alleen niet zo heel lastig :) Maar bedenk dat hardware PWM gewoon 62kHz kan doen ;D

Ik ga er van uit dat de Arduino een PWM signaal genereert op poorten 5 en 6 en dat dit signaal door de shield wordt gebruikt (versterkt) om de lok aan te sturen.
Soort van inderdaad. Het schakelt de hogere railspanning net zo in en uit als het PWM signaal. En daarnaast kan het de polariteit omdraaien door andere pinnen hoog/laag te maken.


Timo
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: jmu op 22 november 2017, 10:22:44
Dag Timo,

Bedankt voor dit verhelderende college. Ik ga er mee aan de slag.

Joop
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: jmu op 03 december 2017, 15:00:02
Ik heb de schakeling gemaakt en stuur nu via pin 3 mijn DFRobot shield aan. En ik moet zeggen, dat gaat prima! De lokjes reageren erg goed en kunnen echt heel langzaam rijden. Ook het starten gaat prima.
Vervolgens heb ik de tabellen met waardes in een formule omgezet (kwadratische formule, gaat tot ong 95% goed, daarna een  kleine afwijking). En alles aangesloten op een testbaantje met 2 reedcontacten. De pendelbaan loopt prima.

Maar ik zit nog met een vraag: ik stuur nu via pin 3 één van de uitgangen van de shield aan. Ik zou echter ook de tweede uitgang via pin 11 willen aansturen, maar wel onafhankelijk van pin 3. Als ik het goed begrijp wordt register OCR2A gebruikt voor de frequentie en register OCR2B voor de snelheid (pulsbreedte), maar wel allemaal gebaseerd op timer 2 en pin 3. Die frequentie geldt dan ook voor pin 11 (zelfde timer), maar hoe kan ik dan de pulsbreedte van pin 11 onafhankelijk aanpassen? Welk register wordt daarvoor gebruikt? Dat de freq niet afzonderlijk aangepast kan worden, daar kan ik mee leven.

Ik wil de tweede poort van de shield gebruiken voor een stukje rangeerspoor waar een lokje wat heen en weer rijdt.

Joop
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: Timo op 04 december 2017, 10:07:25
Hoi Joop,

Zou je de code hier ook willen plaatsen? Altijd leuk om te zien. Graag wel tussen code-tags ([code][/code]).

Wat betreft een tweede pin, even wat reverse engineeren.

PWM van pin 11 en 3 is OC2A en OC2B respectievelijk.
WMG is 101 ofwel mode 5: "PWM, Phase Correct" met OCR2A als TOP.
COM2A0 (icm WMG mode 5) geeft "Toggle OC2A on Compare Match".
COM2B1 geeft "Clear OC2B on Compare Match when up-counting. Set OC2B on Compare Match when down-counting" ofwel non-iverted.

OCR2A is het compare register voor OC2A ofwel pin 11 en OCR2B is het compare register voor OC2B ofwel pin 3. Probleem zit hem er in dat mode 5 gebruikt wordt. Daarbij wordt OCR2A niet alleen gebruikt voor OC2A maar ook als TOP. Hiermee is het inderdaad mogelijk de PWM frequentie aan te passen. Maar hierdoor is het alleen niet meer mogelijk een losse compare match te doen voor pin 11.

Vier opties voor een tweede uitgang:

Ik denk dat ik voor optie 3 of 4 zou gaan. Mijn eerste gedachten was überhaupt optie 4 maar aangezien deze phase correct best netjes is en je timer1 toch niet nodig hebt (geen servo's of tone()) is dat ook een makkelijke optie.


Timo
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: jmu op 04 december 2017, 13:25:17
Dag Timo,

Wederom dank voor jouw uitleg. Dit is wel hogere wiskunde en zelfs voor iemand met een technische achtergrond niet eenvoudig te doorgronden. Maar ik ga er steeds meer van snappen!
Doordat OCR2A als topwaarde gebruikt wordt, en dus direct voor de freq verantwoordelijk is, is het dus niet mogelijk hiermee een regelbare tweede uitgang te realiseren. De andere opties die jij geeft lijken me allemaal een beetje een "te ver van mijn bed" oplossing, maar optie 4 lijkt me steeds meer iets waarmee ik aan de slag wil gaan. Ik ben alleen benieuwd of ik de max freq van ongeveer 70 Hz ga halen in een Loop waarin nog meer acties worden uitgevoerd. Helaas heb ik geen scoop om het te controleren, wellicht kan ik softwarematig nog wat inbouwen om te "meten".

De code zal ik wat opschonen en binnenkort plaatsen.

Joop
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: Timo op 04 december 2017, 13:41:52
70Hz of zelfs 100Hz is nog steeds ergggggggggggg traag voor een Arduino die draait op 16Mhz. Dat is 160.000 cycles per uitgangscycle. je moet alleen zorgen dat het allemaal stappen zijn die de boel niet ophouden (non-blocking). Wat wil je allemaal nog meer gaan doen?

Wat betreft geen scope, een multimeter met duty en freqentie meting kan al helpen. Of een soundcard scope (https://www.google.nl/search?q=soundcard+scope) kan handig zijn.


Timo
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: jmu op 04 december 2017, 17:52:42
Dag Timo,

Bij deze een eerste opzet van een software PWM. Ik ben nog niet tevreden met het resultaat, want het frequentie verloop klopt volgens mij niet. Dat resulteert in een slecht rijdende lok. Dus dat is nog wat knutselen. En ik heb nog niet de tweede uitgang getest.

// PWM-test-3
// Translate potmeter position into frequence and duty cycle of PWM signal
// Software PWM

typedef struct pwmPins {
  int pin;
  unsigned long cyclus;
  unsigned long startCyclus;
  unsigned long toggle;
  bool pinState;
} pwmPin;

/*-----( Define constants and variables )------*/
unsigned long pwm1;        // Value read from A03 to give PWM duty cycle output in terms // of 0-5V
unsigned long potMeter;

unsigned long currentMicros  = micros();
unsigned long previousMicros = 0;
unsigned long microInterval  = 500;
unsigned long lastDebug      = 0;
const byte pwmMax            = 100;

const int pinCount           = 2;
const byte pins[pinCount]    = {3,5};

pwmPin myPWMpins[pinCount];

const byte pinButton    = 2;
const byte pinPotmeter  = 3;
const byte pinMotor1    = 4;
const byte pinMotor2    = 5;
const byte pinTimer2a   = 3;
const byte pinTimer2b   = 11;
const byte MaxStep      = 64;
const byte ledPin       = 13;


void setup()
{
  Serial.begin(9600);
  Serial.println( "Software PWM oplossing (test)");
 
  // Initialize motor pins
  pinMode(ledPin   , OUTPUT);       // ledje voor aan/uit
  pinMode(pinMotor1, OUTPUT);       // bepaalt de richting
  pinMode(pinMotor2, OUTPUT);       // idem
  pinMode(pinButton, INPUT_PULLUP );

  // Set motor pins unequal to ensure movement controlled by enable
  digitalWrite(pinMotor1, HIGH);
  digitalWrite(pinMotor2, LOW);

  setupPWMpins();
}

void setupPWMpins() {
  for (int index=0; index < pinCount; index++) {
    // zet pinnummer in structure:
    myPWMpins[index].pin = pins[index];
 
    // initiele waardes:
    myPWMpins[index].pinState = HIGH;
 
    // noodzakelijk:
    pinMode(pins[index], OUTPUT);
  }
}

byte getPotmeterSetting()
{
  byte iCheck = 0;
  int speed = 0;
 
  // Read potmeter value;
  potMeter = analogRead(pinPotmeter);
  speed = map( potMeter, 0, 1023, -1 * pwmMax, pwmMax );

  if (abs(speed) < 5){speed = 0;}

  // led uit bij snelheid onder 5:
  digitalWrite( ledPin, (abs(speed)>=5));

  // bepaal richting:
  if (speed < 0) {digitalWrite(pinMotor1, LOW);} else {digitalWrite(pinMotor1, HIGH);}
           
  // Determine matching index value and return it
  return (abs(speed));
}

void setPWM( byte index, int snelheid ) {
  // index is 0 voor de eerste en 1 voor de tweede poort
  // snelheid is op een basis van 0 .. 100

  // bereken de waardes voor de freq en de cyclus:
  unsigned int freq = snelheid + 30;
  myPWMpins[index].cyclus = 1.00 / freq * 1000000;

  // bepaal nu de duty cycle en druk die uit in micro sec:
  myPWMpins[index].toggle=myPWMpins[index].cyclus*snelheid/100;

  // Display various variables every 2 sec:
  if (millis() - lastDebug > 2000){
    Serial.print(potMeter);
    Serial.print(" => ");
    Serial.print(snelheid);
    Serial.print(" / ");
    Serial.print(myPWMpins[index].cyclus);
    Serial.print(" µs - ");
    Serial.print(freq);
    Serial.print("Hz - toggle ");
    Serial.print(myPWMpins[index].toggle);
    Serial.println("µs");
    lastDebug = millis();
  }
}

void loop()
{
 
  // Check potmeter value and set frequency and duty cycle accordingly
  setPWM( 0, getPotmeterSetting( ));
  handlePWM();
}

void handlePWM() {
  unsigned long diffMicroSec;

  currentMicros = micros();
 
  // check het interval
  if (currentMicros - previousMicros >= microInterval) {
   
    // alle pinnen aflopen in de array met structures:
    for (int index=0; index < pinCount; index++) {
      // bereken eerst het verschil ( wordt 2 keer gebruikt):
      diffMicroSec = currentMicros - myPWMpins[index].startCyclus;
     
      // forceer stroom uit bij snelheid 0:
      if (myPWMpins[index].toggle < 10) {
        myPWMpins[index].pinState = LOW; 
      } else {
     
        // elke pin heeft eigen waardes
        if (diffMicroSec >= myPWMpins[index].toggle ) {
   
           // zet pin LOW:
           myPWMpins[index].pinState = LOW;
        }
       
        // bij bereiken van max terug naar start:
        if (diffMicroSec >= myPWMpins[index].cyclus ) {
   
           // zet pin HIGH en teller op nul:
           myPWMpins[index].pinState = HIGH;
           myPWMpins[index].startCyclus = currentMicros;
        }
      }
      // stuur de pin aan:
      digitalWrite(myPWMpins[index].pin,
                    myPWMpins[index].pinState);
    }

    // reset micros() tick counter.
    previousMicros = currentMicros;
  }
}

Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: Timo op 04 december 2017, 21:44:39
Hoi Joop,

Ik ga even over de code zoals ik het tegen kom. Lijkt misschien gezeur om het zo te lezen maar zo bedoel ik het niet! Probeer je tot een goed programma te laten komen :)

typedef struct pwmPins {
  int pin;
  unsigned long cyclus;
  unsigned long startCyclus;
  unsigned long toggle;
} pwmPin;

byte is groot genoeg voor een pin nummer. De pinState kun je ook gewoon uitlezen. Daarnaast zet je de initiële waarde van de pinState op HIGH terwijl de pin initiëel laag is.

Ook mag het in C++ direct:
struct pwmPin_t{
  int pin;
  unsigned long cyclus;
  unsigned long startCyclus;
  unsigned long toggle;
  bool pinState;
};

pwmPin_t pwmObjects[] = {
  {3}, {5}
};
const byte NrPwmObjects = sizeof(pwmObjects)/sizeof(pwmObjects[0]);
//ik gebruik vaak de macro
//#define numberOf(x) (sizeof(x)/sizeof(x[0]))
//dan kan je schrijven
//const byte NrPwmObjects = numberOf(pwmObjects);

En eigenlijk ben je met die struct en de setPWM functie al goed op weg om het een object te maken ;)

const byte pinMotor1    = 4;
const byte pinMotor2    = 5;
Zou ook een uitgelezen plek zijn voor een array ;)


unsigned long currentMicros  = micros();Doet niets, je kunt pas een functie aanroepen in een functie.

const byte pinPotmeter  = 3;Als je A3 gebruikt ipv 3 kan je nooit voor gekke verrassingen komen te staan. Want er zijn een aantal Arduino's waar analogRead(3) en analogRead(A3) niet hetzelfde doen.

pwm1 is nooit gebruikt en potmeter als global is niet zo zinvol.

if (speed < 0) {digitalWrite(pinMotor1, LOW);} else {digitalWrite(pinMotor1, HIGH);}Probeer dingen niet op één regel te proppen. Regels (en spaties) zijn gratis (maar overdrijf het ook niet).
if (speed < 0) {
    digitalWrite(pinMotor1, LOW);
  }
  else {
    digitalWrite(pinMotor1, HIGH);
  }
En moet je pinMotor2 ook niet aan passen? Of welke H-brug gebruik je eigenlijk?

getPotmeterSetting()Het is ook niet erg logisch dat deze functie de richting zet. Zou je namelijk niet verwachten aan de naam ;)

Dan meer naar de werking:
unsigned int freq = snelheid + 30;Okay, frequentie tussen 30 en 130 dus.

pwmObjects[index].cyclus = 1.00 / freq * 1000000;De float cast maakt het wel wat lastig maar zorgt denk ik voor de correcte afronding. Maar is hetzelfde als
pwmObjects[index].cyclus = (1000000 + (freq / 2) ) / freq;Maar in ieder geval de duur van een periode in us.

pwmObjects[index].toggle=pwmObjects[index].cyclus*snelheid/100;Hoeveel daar van aan.

Duurde even voor ik dat door had. period en onPeriode ofzo zou het duidelijker hebben gemaakt.

Ik zou het daarna overigens niet eens meer in 500us intervallen hakken maar gewoon checken. Zou eerder het aantal analogReads() beperken. Zeker omdat 500us nu best een grove afronding geeft. Zie deze grafieken (https://docs.google.com/spreadsheets/d/1tRuYnk-tFYA7Iugz1cic2VESVYXB8Uy2M4L1x3LYvD8/edit?usp=sharing) wat voor variatie je nu hebt.

Ik zou het dus allemaal iets directer doen :)

Hopelijk is het niet te veel commentaar :angel:


Timo
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: jmu op 05 december 2017, 10:07:14
Dag Timo,

Bedankt voor je correcties. De source was idd nog niet op orde en was hier en daar snel bij elkaar gekopieerd. Maar goede tips zijn altijd welkom, daar hoef je je niet voor te excuseren!
Kost het uitlezen van de pinState meer processor stappen? Dat is de reden dat ik vaak uitwijk naar een var.

Jouw berekening pwmObjects[index].cyclus = (1000000 + (freq / 2) ) / freq; levert een andere uitkomst. Het scheelt weliswaar niet veel (een half), maar waarom zou je het op die wijze doen?

Op jouw grafiek moet ik nog even studeren en het finetunen moet nog gebeuren. Ik heb iig al de freq berekening aangepast, omdat naar mijn zijn de freq te snel steeg. De formule is nu freq = 0.3 * snelheid + 30;

Joop
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: jmu op 05 december 2017, 17:11:23
Ik heb nog geprobeerd om een software oscilloscoop aan de praat te krijgen, maar dat loopt op een teleurstelling uit. Zelfs al zet ik een toongenerator op de ingang, dan nog is het signaal niet bruikbaar. Helaas lukt het me niet om zo de blokgolf te kunnen onderzoeken. Als iemand nog een tip heeft houd ik me aanbevolen.

Joop
Titel: Re: PWM met frequentieregeling met Arduino t.b.v. besturing analoge DC-treinbaan
Bericht door: Timo op 05 december 2017, 21:05:14
Maar goede tips zijn altijd welkom, daar hoef je je niet voor te excuseren!
Gelukkig! 8) Het was namelijk nogal een rommelig zooitje tips geworden ::)

Kost het uitlezen van de pinState meer processor stappen? Dat is de reden dat ik vaak uitwijk naar een var.
Iets, maar als je ook digitalWrite() gebruikt is het verwaarloosbaar.

Jouw berekening pwmObjects[index].cyclus = (1000000 + (freq / 2) ) / freq; levert een andere uitkomst. Het scheelt weliswaar niet veel (een half), maar waarom zou je het op die wijze doen?
Zou kunnen dat jouw berekening juist niet correct afrondde (altijd naar beneden). Dat is precies wat ik hier fix met "+ (freq / 2) )". Voorbeeldje, met integer math 10 / 4 = 2. Terwijl als we het normaal doen is het 2,5 wat afgerond 3 geeft. Als je de teller verhoogd met de helft van de noemer zal integer math ook correct afronden. In het voorbeeld, (10 + (4/2) ) / 4 = (10 + 2) / 4 = 12 / 4 = 3. Correct afgerond  :)

Waarom je liever bij integer math blijft? De standaard, 8-bit, Arduino's hebben geen hardware voor floating point math. De compiler weet dit en werkt er om heen door het op te breken in een berg integer math. Maar dat is dus altijd een stuk trager dan het te doen in integer math. Dat is ook waarom je op 8-bit microcontroller (of meer algemeen, microcontroller zonder floating point hardware) liever gewoon de decimaal weg haalt. Dus als je euros wilt met centen achter de komma sla je hetgewoon op als centen. Wil je graden Celsius met één decimaal sla je het op als deci-graden Celsius. Dit punt zet je er zo weer in als je het wilt printen.

Op jouw grafiek moet ik nog even studeren en het finetunen moet nog gebeuren. Ik heb iig al de freq berekening aangepast, omdat naar mijn zijn de freq te snel steeg. De formule is nu freq = 0.3 * snelheid + 30;
Maar met die formule loopt je frequentie tussen de 30Hz en 60Hz... Dat is wel een heeeeeeel verschil met eerst. En weer, in integer math is het een stuk sneller. Okay, snelheid / 3 + 30 is niet helemaal hetzelfde maar wel een stuk sneller. Voorbeeldje:
volatile byte in = 10;
volatile byte out;
unsigned long tic, toc;

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

  Serial.println(F("---Float---"));
  tic = micros();
  for(in = 0; in <= 100; in++){
    out = 0.3 * in + 30;
  }
  toc = micros();
  Serial.print(F("Waarde: "));
  Serial.println(out);
  Serial.print(F("tijd: "));
  Serial.println(toc - tic);
 
  Serial.println(F("---Int---"));
  tic = micros();
  for(in = 0; in <= 100; in++){
    out = in / 3 + 30;
  }
  toc = micros();
  Serial.print(F("Waarde: "));
  Serial.println(out);
  Serial.print(F("tijd: "));
  Serial.println(toc - tic);
}

void loop(){
}
Uitkomst:
Citaat
---Float---
Waarde: 60
tijd: 2472
---Int---
Waarde: 63
tijd: 152
Goed, daar zie je al het verschil in uitkomst maar ook het enorme verschil in tijd. Namelijk 16 keer zo snel.

Zelf ooit wel een software oscilloscoop gebruikt maar niet veel en dat is lang geleden. Staat al een aardig tijdje een HP scope op me bureau :angel: Maar voor de geluidskaart oscilloscoop zal het nooit lukken om een blokgolf echt netjes weer te geven, zeker met die lage frequenties. Dat komt door de ontkoppel condensator in de geluidskaart waardoor je het altijd AC koppelt. Was ik even vergeten toen ik het noemde. Als je een goedkope USB geluidskaart gebruikt is deze condensator wel weg te halen. Maar voor blokgolven is de logic analyzergoedkope logic analyzer (https://www.ebay.nl/itm/USB-Logic-Analyzer-24MHz-8-Channel-UART-IIC-SPI-Debug-for-MCU-FPGA-ARM/191685084604) makkelijker.


Timo