Arduino - wat kun je er mee?
Re: Arduino - wat kun je er mee?
Zo aan het geluid van het motortje te horen maakt dat toch al meer dan "een paar" omwentelingen. Het zou me verbazen als er nog ernstige afwijkingen zitten in de berekening van Rob.
Verder was het te verwachten dat een kabel een hoop extra koppel zou vragen.
Goed bezig.
Verder was het te verwachten dat een kabel een hoop extra koppel zou vragen.
Goed bezig.
Re: Arduino - wat kun je er mee?
Vorige week heb ik een test gedaan met een stappenmotor. Het stroom- en spanningsverloop was interessant:
rpm A kmh V
300 19,4 28 11,35
350 16,6 30 11,43
400 14,4 35 11,52
450 13,3 40 11,67
500 13,3 40 11,8
525 12,7 45 12,06
530 12,5 46 12,13
550 12,8 50 12,16
Maar ik had nog niet uitgevonden hoe je een stappenmotor accelereert dus toen ik naar de 600 toeren wilde, heb ik de driver opgefikt.
Dat heeft me wel weer aan het denken gezet. Ik zat op het spoor van een E30-snelheidsmeter maar dat had ik geparkeerd omdat ik niet begreep hoe ik met IC's de frequentie kon veranderen. Maar nu ik wel heb geleerd met de Arduino hoe het een en ander kan, en ik niet zoveel zin meer had in drivers en dat soort dingen, heb ik de E30-teller weer tevoorschijn gehaald.
Ik had wat last van gekke storingen, maar na een tijdje landde het kwartje: Mijn acculader, die ik als voeding gebruikte, is ook modulerend, dat zorgde voor heel erg gekke resultaten op de meter. Maar nu met een echte gelijkstroombron kan ik zonder problemen de E30-teller besturen. Geen elektromechanisch gedoe meer en vooral geen risico dat de boel affikt.
Nu dus de Hall-sensor onder de auto monteren en de Arduino gaat nu niet veel anders doen dan de frequentie van de puls van de Hall-sensor veranderen.
rpm A kmh V
300 19,4 28 11,35
350 16,6 30 11,43
400 14,4 35 11,52
450 13,3 40 11,67
500 13,3 40 11,8
525 12,7 45 12,06
530 12,5 46 12,13
550 12,8 50 12,16
Maar ik had nog niet uitgevonden hoe je een stappenmotor accelereert dus toen ik naar de 600 toeren wilde, heb ik de driver opgefikt.
Dat heeft me wel weer aan het denken gezet. Ik zat op het spoor van een E30-snelheidsmeter maar dat had ik geparkeerd omdat ik niet begreep hoe ik met IC's de frequentie kon veranderen. Maar nu ik wel heb geleerd met de Arduino hoe het een en ander kan, en ik niet zoveel zin meer had in drivers en dat soort dingen, heb ik de E30-teller weer tevoorschijn gehaald.
Ik had wat last van gekke storingen, maar na een tijdje landde het kwartje: Mijn acculader, die ik als voeding gebruikte, is ook modulerend, dat zorgde voor heel erg gekke resultaten op de meter. Maar nu met een echte gelijkstroombron kan ik zonder problemen de E30-teller besturen. Geen elektromechanisch gedoe meer en vooral geen risico dat de boel affikt.
Nu dus de Hall-sensor onder de auto monteren en de Arduino gaat nu niet veel anders doen dan de frequentie van de puls van de Hall-sensor veranderen.
- BertjeConti
- E21 Mad
- Posts: 3012
- Joined: Mon Nov 04, 2013 9:49 pm
- My E21(s): E12 520-6
- Location: nederland , Weert
Re: Arduino - wat kun je er mee?
Leuk he, zo zie je hoe het één tot het ander kan leiden.
Maar definitief op de goede weg nu.
Sluit je de hall sensor aan op D2? Dan kun je met een interrupt werken, ideaal om zo de pulstijd te bepalen en aan de hand daarvan een blokgolf met de juiste frequentie uit te sturen op een andere poort
Ben benieuwd naar je scetch.
Maar definitief op de goede weg nu.
Sluit je de hall sensor aan op D2? Dan kun je met een interrupt werken, ideaal om zo de pulstijd te bepalen en aan de hand daarvan een blokgolf met de juiste frequentie uit te sturen op een andere poort
Ben benieuwd naar je scetch.
Megasquirted '77 E12 520-6
Aspen Silver '96 E39 523i
Re: Arduino - wat kun je er mee?
Ik zat in eerste instantie aan zoiets te denken:
Looptime definieer ik als 500ms of iets dergelijks.
Om dan elke 500ms de snelheidsmeter bij te sturen door middel van iets dergelijks:
digitalWrite(OUTPUT, HIGH);
delayMicroseconds(pulse);
digitalWrite(OUTPUT, LOW);
delayMicroseconds(pulse);
Looptime definieer ik als 500ms of iets dergelijks.
Code: Select all
while ((millis() - starttime) <= looptime) // Measure the RPM for a certain amount of time
{
sensorState = digitalRead(sensorPin); // Read the status on input pin:
if (sensorState != lastSensorState) { //Is not equal to
if (sensorState == HIGH) {
RPM++;
}
lastSensorState = sensorState;
}
} //End of RPM measurement block
Om dan elke 500ms de snelheidsmeter bij te sturen door middel van iets dergelijks:
digitalWrite(OUTPUT, HIGH);
delayMicroseconds(pulse);
digitalWrite(OUTPUT, LOW);
delayMicroseconds(pulse);
- BertjeConti
- E21 Mad
- Posts: 3012
- Joined: Mon Nov 04, 2013 9:49 pm
- My E21(s): E12 520-6
- Location: nederland , Weert
Re: Arduino - wat kun je er mee?
Ik heb inmiddels best veel ervaring met het meten van de actuele snelheid. Het wordt in m'n display gebruikt dat aan de megasquirt hangt, en nog belangrijker, in mijn tripmeter die we gebruiken tijdens de rally's.
Met elke puls van de hall sensor een interrupt starten is echt de gemakkelijkste manier om de tijd tussen twee pulsen te bepalen. Deze tijd bepaald dan je snelheid.
Omdat de tijden tussen de pulsen nog kunnen verschillen door bijvoorbeeld een triggerwiel met niet exact gelijke tanden, bepaal ik de gemiddelse tijd van de laatste 10 pulsen.
Dan heb je nog één ding, en dat is stil staan. In mijn toepassing is de snelheid pas 0 als er 2 sec geen pulsen ontvangen zijn.
Uiteindelijk kun je dan met de pulstijd een omgerekende blokgolf aansturen.
Met elke puls van de hall sensor een interrupt starten is echt de gemakkelijkste manier om de tijd tussen twee pulsen te bepalen. Deze tijd bepaald dan je snelheid.
Omdat de tijden tussen de pulsen nog kunnen verschillen door bijvoorbeeld een triggerwiel met niet exact gelijke tanden, bepaal ik de gemiddelse tijd van de laatste 10 pulsen.
Dan heb je nog één ding, en dat is stil staan. In mijn toepassing is de snelheid pas 0 als er 2 sec geen pulsen ontvangen zijn.
Uiteindelijk kun je dan met de pulstijd een omgerekende blokgolf aansturen.
Megasquirted '77 E12 520-6
Aspen Silver '96 E39 523i
- BertjeConti
- E21 Mad
- Posts: 3012
- Joined: Mon Nov 04, 2013 9:49 pm
- My E21(s): E12 520-6
- Location: nederland , Weert
Re: Arduino - wat kun je er mee?
Hieronder heb ik wat stukken code uit mijn tripmaster gecopieerd, welke je misschien op weg kunnen helpen.
variabelen definieren, ik laat alleen zien wat nodig is voor dit voorbeeld. daarnaast wordt de library " SimpleTimer" toegevoegd:
in de setup koppel je een routine aan interrupt 0, interrupt 0 is ingang D2, de interrupt rourtine wordt aangeroepen op de neergaande flank van de puls van de sensor (bij jou hall sensor, bij mij een proximity sensor)
Ook wordt een 200mS timer geinitialiseerd:
in de interrupt routine wordt de actuele tijd in microseconden opgeslagen in de variabele pulseT, daarnaast wordt de bool 'puls' geset.
in de loop routine wordt continu gecontroleerd of er een nieuwe "speedpulse" binnen is gekomen, zo ja, dan wordt de tijd tussen de vorige puls en de huidige puls uitgerekend, de gemiddelde pulstijd bijgewerkt, en de huidige tijd opgeslagen. daarnaast een paar bools gereset.
Ook wordt een timer aangetikt (dit is nodig om de timer goed te laten werken). deze timer loopt elke 200mS en doet in mijn geval al het overige werk.
de gemiddelde pulstijd staat in de variabele "deltaT", deze wordt dan weer in de 200mS timer routine gebruikt om de actuele snelheid weer te geven op de display.
met deze routine wordt een gemiddelde pulstijd berekend van de laatste 10 gemeten tijden berekend.
in onderstaande routine , die elke 200mS herhaald wordt, wordt de actuele snelheid berekend en naar een "printspeed" routine gestuurd, de variabele "PulseVal" bevat de omrekenwaarde, het aantal pulsen per 100 meter.
Misschien heb je er wat aan, misschien ook niet.
-------------------------------------------------------------------
mijn tripmaster, op arduino gebaseerd:
variabelen definieren, ik laat alleen zien wat nodig is voor dit voorbeeld. daarnaast wordt de library " SimpleTimer" toegevoegd:
Code: Select all
#include <SimpleTimer.h>
SimpleTimer timer; // timer to do display writings e.d.
int timerID; // variable to store the timer ID
volatile bool puls = false; // true after eacht received puls
volatile bool halted = true; // to check if still receiving pulses
volatile unsigned long pulseT; // stores micros() at each puls
unsigned long prevT,deltaT; // for speed calculation
int PulseVal = 813; // distance unit (pulses per 100 meter travel)
Ook wordt een 200mS timer geinitialiseerd:
Code: Select all
void setup() {
//setup interrupt on D2 (speedpulse input)
attachInterrupt(0, speedpulse, FALLING);
// Setup the 200mS timer
timerID = timer.setInterval(200, timerAction);
}
Code: Select all
// do interrupt D2 stuff, speedpulse received +++++++++++++++++++++++++++++++++++++++++++
void speedpulse(){
pulseT = micros(); // save time interupted
puls = true; // set puls
}
in de loop routine wordt continu gecontroleerd of er een nieuwe "speedpulse" binnen is gekomen, zo ja, dan wordt de tijd tussen de vorige puls en de huidige puls uitgerekend, de gemiddelde pulstijd bijgewerkt, en de huidige tijd opgeslagen. daarnaast een paar bools gereset.
Ook wordt een timer aangetikt (dit is nodig om de timer goed te laten werken). deze timer loopt elke 200mS en doet in mijn geval al het overige werk.
de gemiddelde pulstijd staat in de variabele "deltaT", deze wordt dan weer in de 200mS timer routine gebruikt om de actuele snelheid weer te geven op de display.
Code: Select all
void loop() {
if (puls){
// speed pulse received
deltaT = runningAverage(pulseT-prevT); // calc time between pulses (take average of last 10)
prevT = pulseT; // save 'time' for next round
puls = false; // clear puls
halted = false; // bool to check if minimal 1 pulse received in next round
}
// tick the timer
timer.run();
}
Code: Select all
// function calculating running average out of last 10 elements ++++++++++++++++++++++++++++++++++++++
// making this higher gives faulty speed calculations at higher speeds ( if X elements * deltaT >160mS)
long runningAverage(long M)
{
static long LM[10]; // LastMeasurements
static byte index = 0;
static long sum = 0;
// keep sum updated to improve speed.
sum -= LM[index];
LM[index] = M;
sum += LM[index];
index = (index + 1) % 10;
return sum / 10;
}
in onderstaande routine , die elke 200mS herhaald wordt, wordt de actuele snelheid berekend en naar een "printspeed" routine gestuurd, de variabele "PulseVal" bevat de omrekenwaarde, het aantal pulsen per 100 meter.
Code: Select all
// a function to be executed every 200mS +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void timerAction() {
// now calculate actual speed
if (halted){ // check is still received minimal 1 pulse in 200mS
calcSpeed = 0;
}
else{
calcSpeed = ((360000000/PulseVal)/deltaT);
}
printSpeed(calcSpeed);
halted = true;
}
-------------------------------------------------------------------
mijn tripmaster, op arduino gebaseerd:
Megasquirted '77 E12 520-6
Aspen Silver '96 E39 523i
Re: Arduino - wat kun je er mee?
Goeie tip!
Even snel dan wordt het zoiets:
Dan moet ik alleen nog een plekje voor deze vinden:
digitalWrite(OUTPUT, HIGH);
delayMicroseconds(blokgolf);
digitalWrite(OUTPUT, LOW);
delayMicroseconds(blokgolf);
Haha, ik was al aan het schrijven. Ik ga dat nu eerst eens even lezen. Leuk om niet alleen maar met schokbrekers en roest bezig te zijn en iemand gevonden die hebben die dat ook vind!
Even snel dan wordt het zoiets:
Code: Select all
looptime = 500
boutencardan = 6
secfactor = (1000/looptime)
eenofandererekenfactor = xx
void setup(){
attachInterrupt(digitalPinToInterrupt(2), cardan, FALLING)
}
void loop(){
if ((millis() - starttime) >= looptime){
detachInterrupt(digitalPinToInterrupt(2))
RPM = secfactor * (1/boutencardan) * 60 * pulsen
blokgolf = RPM * eenofandererekenfactor
pulsen = 0
starttime = millis()
attachInterrupt(digitalPinToInterrupt(2), cardan, FALLING)
}
}
void cardan(){
pulsen ++
}
digitalWrite(OUTPUT, HIGH);
delayMicroseconds(blokgolf);
digitalWrite(OUTPUT, LOW);
delayMicroseconds(blokgolf);
Haha, ik was al aan het schrijven. Ik ga dat nu eerst eens even lezen. Leuk om niet alleen maar met schokbrekers en roest bezig te zijn en iemand gevonden die hebben die dat ook vind!
Re: Arduino - wat kun je er mee?
Ik kwam er niet uit met het voortschrijdend gemiddelde en met de interrupt. Het is toch nog een stapje te hoog voor mij om dit te beheersen merk ik.
Maar ik geloof dat dit toch redelijk eenvoudige code is die ook nog lijkt te werken. Ik neem te tijd voor 6 bouten om te passeren en op die manier demp ik onregelmatigheden. Hoop ik. In plaats van een vierkante golf knippert nu het ledje op de PCB. Die factor wordt uiteraard nog anders.
Maar ik geloof dat dit toch redelijk eenvoudige code is die ook nog lijkt te werken. Ik neem te tijd voor 6 bouten om te passeren en op die manier demp ik onregelmatigheden. Hoop ik. In plaats van een vierkante golf knippert nu het ledje op de PCB. Die factor wordt uiteraard nog anders.
Code: Select all
////////// Pin definition
int OUT_PIN = LED_BUILTIN ;
int IN_PIN = 7 ;
////////// Define all constants
int bolts = 6; // The number of bolts to count
unsigned long factor = 6; // The factor to multiply one rotation of the driveshaft with to create the square wave
int treshold = 3000; // Define a treshold for the stop timer to end the squarewave
////////// Define all starting values
byte in_was = LOW; // Concept: Look for transitions; need state memory
byte in_now; // Read once per cycle
int squareState = LOW; // Variable for the square wave
int Tround = 0; // The time for the drive shaft to go round once
int count = 0; // A counter to count the six bolts of the driveshaft
int start = 0; // A timer to time the time to count six bolts
int ticker = 0; // A ticker needed to only start the wave again after being stopped after a whole rotation of the driveshaft
unsigned long freq = 1000; // The frequency of the square wave
unsigned long stoptimer = millis(); // A timer to stop the wave if it takes too long
unsigned long previousmillis = 0; // For the square wave (BlinkWithoutDelay)
unsigned long currentmillis = millis(); // For the square wave (BlinkWithoutDelay)
void setup() {
pinMode(OUT_PIN, OUTPUT);
pinMode(IN_PIN, INPUT);
Serial.begin(9600);
}
void loop()
{
in_now = digitalRead(IN_PIN); // Read the current state of the input
if (in_was == HIGH) { // Were we high or low?
if (in_now == LOW) { // If this statement is true, we have transitioned from high to low
in_was = LOW; // Set the was-state to the current state
count ++; // Start counting for six bolts to pass
stoptimer = millis() ; // Start a stop timer to end the cycle if it takes too long
// Serial.print(count); //Print result
if (count == 1) { // When the first bolt in a rotation passes, start a clock to time 6 bolts to pass
start = millis();
}
}
}
else { // If the previous state was not HIGH, ie LOW, and it if it is HIGH by now, we have again a change
if (in_now == HIGH) { // So, has transitioned from low to high
in_was = HIGH; // Set the state to the new current state
}
}
if (count == bolts) { // If we have counted the number of bolts count, there has been one rotation of the driveshaft
count = 0; // Reset the counter
Tround = (millis() - start); // Calculate the time that took the driveshaft to turn one rotation
ticker = 1; // Ticker is high after one rotation
}
unsigned long currentmillis = millis(); // Update the timer for the BlinkWithoutDelay
freq = Tround / factor; // This is the equation to fix the frequency to put out
if ((millis() - stoptimer) < treshold && ticker != 0) { // If the stop timer does not need to stop, proceed
if (currentmillis - previousmillis >= freq) { // If the difference is larger than the frequence, it is time to change this
previousmillis = currentmillis; //Save the last time the square wave changed
if (squareState == LOW) { // If the wave is low, turn it to high and vice-versa
squareState = HIGH;
} else {
squareState = LOW;
}
digitalWrite(OUT_PIN, squareState); // set the wave with the squareState of the variable:
}
}
else {
digitalWrite(OUT_PIN, LOW); // If there is no signal for the amount of the treshold, go to low
ticker = 0; // The ticker is reset
}
}
- BertjeConti
- E21 Mad
- Posts: 3012
- Joined: Mon Nov 04, 2013 9:49 pm
- My E21(s): E12 520-6
- Location: nederland , Weert
Re: Arduino - wat kun je er mee?
Is het niet slimmer de 4 bouten van de cardanas te tellen? Die draait 4keer sneller rond, en zo zit je sensor ook nog eens beter beachermd.
Zo doet de sensor bij mij het al ruim 12 jaar prima.
Die is er toen onder gekomen vooe een signaal voor de cruise control.
Ik heb toen het aantal pulsen door 2 moeten delen voor een juist snelheid signaal voor de cruise, gewoon met een flip-flopje gedaan.
Zo doet de sensor bij mij het al ruim 12 jaar prima.
Die is er toen onder gekomen vooe een signaal voor de cruise control.
Ik heb toen het aantal pulsen door 2 moeten delen voor een juist snelheid signaal voor de cruise, gewoon met een flip-flopje gedaan.
Megasquirted '77 E12 520-6
Aspen Silver '96 E39 523i
- BertjeConti
- E21 Mad
- Posts: 3012
- Joined: Mon Nov 04, 2013 9:49 pm
- My E21(s): E12 520-6
- Location: nederland , Weert
Re: Arduino - wat kun je er mee?
Jan Willem, ik heb je sketch even in een arduino geladen, en ondanks het vele aantal regels werkt je sketch verrassend simpel, en dat geeft helemaal niks als het microcontrollertje toch niks anders hoeft te doen.Wilmo wrote:Ik kwam er niet uit met het voortschrijdend gemiddelde en met de interrupt. Het is toch nog een stapje te hoog voor mij om dit te beheersen merk ik.
Maar ik geloof dat dit toch redelijk eenvoudige code is die ook nog lijkt te werken. Ik neem te tijd voor 6 bouten om te passeren en op die manier demp ik onregelmatigheden. Hoop ik. In plaats van een vierkante golf knippert nu het ledje op de PCB. Die factor wordt uiteraard nog anders.
Code: Select all
////////// Pin definition int OUT_PIN = LED_BUILTIN ; int IN_PIN = 7 ; ////////// Define all constants int bolts = 6; // The number of bolts to count unsigned long factor = 6; // The factor to multiply one rotation of the driveshaft with to create the square wave int treshold = 3000; // Define a treshold for the stop timer to end the squarewave ////////// Define all starting values byte in_was = LOW; // Concept: Look for transitions; need state memory byte in_now; // Read once per cycle int squareState = LOW; // Variable for the square wave int Tround = 0; // The time for the drive shaft to go round once int count = 0; // A counter to count the six bolts of the driveshaft int start = 0; // A timer to time the time to count six bolts int ticker = 0; // A ticker needed to only start the wave again after being stopped after a whole rotation of the driveshaft unsigned long freq = 1000; // The frequency of the square wave unsigned long stoptimer = millis(); // A timer to stop the wave if it takes too long unsigned long previousmillis = 0; // For the square wave (BlinkWithoutDelay) unsigned long currentmillis = millis(); // For the square wave (BlinkWithoutDelay) void setup() { pinMode(OUT_PIN, OUTPUT); pinMode(IN_PIN, INPUT); Serial.begin(9600); } void loop() { in_now = digitalRead(IN_PIN); // Read the current state of the input if (in_was == HIGH) { // Were we high or low? if (in_now == LOW) { // If this statement is true, we have transitioned from high to low in_was = LOW; // Set the was-state to the current state count ++; // Start counting for six bolts to pass stoptimer = millis() ; // Start a stop timer to end the cycle if it takes too long // Serial.print(count); //Print result if (count == 1) { // When the first bolt in a rotation passes, start a clock to time 6 bolts to pass start = millis(); } } } else { // If the previous state was not HIGH, ie LOW, and it if it is HIGH by now, we have again a change if (in_now == HIGH) { // So, has transitioned from low to high in_was = HIGH; // Set the state to the new current state } } if (count == bolts) { // If we have counted the number of bolts count, there has been one rotation of the driveshaft count = 0; // Reset the counter Tround = (millis() - start); // Calculate the time that took the driveshaft to turn one rotation ticker = 1; // Ticker is high after one rotation } unsigned long currentmillis = millis(); // Update the timer for the BlinkWithoutDelay freq = Tround / factor; // This is the equation to fix the frequency to put out if ((millis() - stoptimer) < treshold && ticker != 0) { // If the stop timer does not need to stop, proceed if (currentmillis - previousmillis >= freq) { // If the difference is larger than the frequence, it is time to change this previousmillis = currentmillis; //Save the last time the square wave changed if (squareState == LOW) { // If the wave is low, turn it to high and vice-versa squareState = HIGH; } else { squareState = LOW; } digitalWrite(OUT_PIN, squareState); // set the wave with the squareState of the variable: } } else { digitalWrite(OUT_PIN, LOW); // If there is no signal for the amount of the treshold, go to low ticker = 0; // The ticker is reset } }
Megasquirted '77 E12 520-6
Aspen Silver '96 E39 523i
Re: Arduino - wat kun je er mee?
We zullen zien wanneer ik aan de limiet kom
Het is nog helemaal niet nodig, maar wel leuk eens met een schermpje te klooien. Deze heeft maar twee in/uitgangen nodig en stroom, dus dat is fijn.
Het is nog helemaal niet nodig, maar wel leuk eens met een schermpje te klooien. Deze heeft maar twee in/uitgangen nodig en stroom, dus dat is fijn.
- BertjeConti
- E21 Mad
- Posts: 3012
- Joined: Mon Nov 04, 2013 9:49 pm
- My E21(s): E12 520-6
- Location: nederland , Weert
Re: Arduino - wat kun je er mee?
Volgens mij heb je de smaak te pakken
Megasquirted '77 E12 520-6
Aspen Silver '96 E39 523i
- Jeroen
- Site Admin
- Posts: 29246
- Joined: Tue Sep 14, 2004 12:23 pm
- My E21(s): '81 323i Baur
- Location: The Netherlands
- Contact:
Re: Arduino - wat kun je er mee?
Heee lachen, met uw welnemen ga ik die ook even misbruiken hahaha!
Regards/groeten, Jeroen
Re: Arduino - wat kun je er mee?
Wat? De foto, de module of wat bedoel je met 'die'?