Waardering:
  • 0 stemmen - gemiddelde waardering is 0
  • 1
  • 2
  • 3
  • 4
  • 5
DHZ vermogensmeter
#27
(23-Feb-2024, 01:39 PM)HugoW1975 schreef: Ik wil dus graag een losse kettingtandwielhouder en een los tandwiel. Een beetje zoals deze al zijn, maar deze wil ik niet vernaggelen. Die moeten er terug op als het toch niet allemaal in één keer geheel vaudloos werkt. Dat gebeurt soms...


Een los tandwiel? Nou ik heb hier nog wel wat losse tandwielen liggen... maar ik denk niet dat dat is wat je bedoeld. Maar wat je nou wel bedoeld weet ik niet.
Antwoord }
Bedankt door: Willeke_IGKT
#28
(23-Feb-2024, 02:25 PM)Merijn schreef: De as (en daarmee het crankstel) is een 10 tegen 1 een vierkante as:
https://www.sheldonbrown.com/harris/bottombrackets.html

Kettingring is een vijf-arm met denk ik 110 mm steekcirkel, maar dat moet je even nameten:
https://www.sheldonbrown.com/harris/chainrings.html

De as is vrijwel gegearanderd vierkant inderdaad, met een klein risico dat het een JIS-as is. Die zijn ook vierkant, maar net iets anders taps.
Quasi-uitwisselbaar met standaard vierkant (als in: je krijgt het vast, maar of het ook weer 'netjes' los komt is een tweede).
Mocht je over willen naar een andere as dan moet je even de getallen op je bottom bracket bestuderen. Als het goed is is daar (op die ringen op de plek waar de as de neuspijp uit komt) iets als "24 x 36" (= millimeters = Italiaans) of "1.37 x iets" (= inches = BSA/Brits) te lezen, als je genoeg vet en vuil hebt verwijderd. BSA komt iets meer voor (de lokale Bianchi dealer hier noemt dat zelf een 'normaal bracket'), maar ik heb ook meerdere Italianen in de schuur hangen. Voor beide systemen zijn probleemloos onderdelen verkrijgbaar.

Bij de 'spider' zou ik juist gokken op 130 BCD vanaf de foto, even nameten dus. (135 BCD bestaat ook, is meestal Campagnolo, andere maten in de buurt van 110 of 130 zijn zeer incourant).
(BCD = bolt circle diameter = steekcirkel, de diameter van een denkbeeldige cirkel door de 5 bladbouten dus).
Airborne Valkyrie - Airborne Carpe Diem - Van Nicholas Euros - Koga Miyata FP Chromo - Optima Baron - Optima Orca - HP Gekko 20 FX
Antwoord }
Bedankt door: Willeke_IGKT
#29
De plannen zijn een beetje gewijzigd, de wens voor een goedkope vermogensmeter niet. Ik vond het concept van het 'zwevende' tandwiel mechanisch niet echt haalbaar. Of in ieder geval niet makkelijk te doen voor een amateur. Bij het maken van mijn bagagedrager keek ik naar de fiets en toen viel me op dat er een kettinggeleidewieltje op het trekkende part zit. Daar komt een kracht op en die kracht varieert met hoe hard de ketting trekt. En dus hoe hard je trapt.

[Afbeelding: pwe8ZKF.jpg]

De hoek tussen de kettingdelen is 168 graden, als ik met 80 kg tegen het pedaal druk (kruklengte, tandwielradius, Piet Agoras, etc), dan heb ik een 16 kg load cell nodig op die plek. Dus 20, want een maatje kleiner op Amazon is meteen 5, en da's wat weinig. Zo, ik weet dan dus koppel.

Vervolgens wil ik op het hoofdtandwiel een inductieve sensor zetten (hier kom ik later nog op terug) en het volgende doen:
Bij iedere puls het koppel meten en accumuleren.
Bij iedere puls een teller ophogen.
Na evenveel pulsen als er tanden op het tandwiel zitten, het gemiddelde koppel van die omwenteling berekenen (accumulatie / aantal pulsen). En ik kan ook meten hoelang dat aantal pulsen geduurd heeft, dus weet ik toerental per seconde. Met koppel en toerental weet ik vermogen. Jee! Gelukt!

Dus ben ik aan de slag gegaan met een Arduino Uno, ik heb de load cell met HX711 versterkertje en de inductieve sensor gekocht. Ik had nog een TM1637 4-cijferig displayjte liggen, perfect voor de toepassing. Voor de testopstelling heb ik de inductieve sensor even door een drukknopje vervangen, zo kan ik makkelijk pulsen genereren. Ik heb code geschreven (daar ben ik nog een beginner in), waarbij ik het aantal tanden per omwenteling even op '5' gezet heb. Dus ik hoef maar 5 keer te drukken op het knopje voor een omwenteling, geen 55 (? Ik moet nog eens echt tellen hoeveel het er zijn op mijn fiets).

[Afbeelding: v00NjKw.jpg]

Dit is de code:
Citaat:[font=Consolas, "Courier New", monospace]/*
02-03-2024 HugoW
This is the sketch for my Arduino based bicyle power gauge.
It uses an Arduino Nano, a TM1637 display, an inductive sensor on the bike's main sprocket
and a load cell with a wheel pressing on the power-part of the chain.
The harder you push on the pedal, the bigger the chain tension.
The sketch records the load cell value at each passing of a tooth and adds those numbers together.
After one full revolution, the accumulated number is devided by the number of teeth, is the average torque (with a bit of
calculating to get from load cell amplifier signal to real torque in Nm). The average torque multiplied by RPS(revolutions per second) is Watts.
*/

// Include libraries:
#include <Arduino.h>
#include <TM1637Display.h>
#include <HX711.h>

// Declare variables and pins:
// For torque measurement and power calculation:
const int LOADCELL_DOUT_PIN = 2;
const int LOADCELL_SCK_PIN = 3;
long Torque;
HX711 scale;
int TorqueSum;
int TorqueTare;
int TorqueFactor;
int Wattage;
// For TM1637 display:
#define CLK 9
#define DIO 10
TM1637Display display = TM1637Display(CLK, DIO);
// For tooth pulse input:
int ToothSensorState;
int ToothSensor = 5;
int ToothState;
int ToothCount;
int NumberOfTeeth;
// For cycle time:
int StartMillis;
int StopMillis;
int CycleDuration;

void setup()
{
// Declare pins and such:
Serial.begin(9600);
scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
pinMode(ToothSensor, INPUT);
// Setup display:
display.clear();
display.setBrightness(7);
// Set changing values to zero
ToothSensorState = 0;
TorqueSum = 0;
StartMillis = 0;
StopMillis = 0;
display.showNumberDec(0, false);
// Set fixed values:
NumberOfTeeth = 5;
TorqueTare = 0;
TorqueFactor = 1;
}

void loop()
{

ToothSensorState = digitalRead(ToothSensor);
if ((ToothSensorState == 1) && (ToothState == 0) && (ToothCount < NumberOfTeeth))
{
  Torque = scale.read();
  ToothState = 1;
  TorqueSum = (TorqueSum + Torque);
  ToothCount = (ToothCount + 1);
}

if ((ToothSensorState == 1) && (ToothState == 0) && (ToothCount >= NumberOfTeeth))
{
  Torque = scale.read();
  ToothState = 1;
  TorqueSum = TorqueSum + Torque;
  ToothCount = 0;
  StopMillis = millis();
  CycleDuration = ((StopMillis - StartMillis) / 1000);
  StartMillis = millis();
  Wattage = (((TorqueSum * -1000 / NumberOfTeeth) - TorqueTare) * TorqueFactor / CycleDuration);
  TorqueSum = 0;
  display.showNumberDec(Wattage, false);
  Serial.println(Wattage);
}

if ((ToothSensorState == 0) && (ToothState == 1))
{
  ToothState = 0;
}


}
[/font]

Het lijkt al een beetje te werken (de factor '-1000' in regel 84 heb ik even toegevoegd voor een toonbaar getal) maar nu komen de problemen uiteraard pas boven. De 'TorqueTare' en de 'TorqueFactor' boeien me nog niet zoveel, dat wordt een kwestie van meten en uitrekenen als de boel op de fiets gemonteerd is. Ijken. Andere dingen boeien mij wel. Zo blijkt mijn HX711 maar 10 signalen per seconden te geven. Da's wel erg weinig. Ik kan dat aanpassen naar 80, dat lijkt me beter. Maar ik krijg bij 150 toeren per minuut van het hoofdtandwiel (heb ik even als max ingeschat, is denk ik wat hoog) en 55 tanden op het tandwiel wel 137,5 pulsen per seconde van de inductieve sensor. Ik weet niet of dat teveel is, het lijkt me wel.

Zo, dat is waar ik nu ben, alle input is welkom. Liefst wel positief opbouwend Wink

Hugo
Antwoord }
Bedankt door: Willeke_IGKT , 365cycle
#30
(03-Mar-2024, 09:31 AM)HugoW1975 schreef: geen 55 (? Ik moet nog eens echt tellen hoeveel het er zijn op mijn fiets).


Bij de meeste voorbladen die ik tegenkom staat het aantal tanden gewoon erop vermeld. Wel is het soms erg zoeken, zeker als er vuil/smeer op het blad zit. Maar tellen kan natuurlijk ook gewoon.
Antwoord }
Bedankt door: Willeke_IGKT
#31
(03-Mar-2024, 09:31 AM)HugoW1975 schreef: (...)
Daar komt een kracht op en die kracht varieert met hoe hard de ketting trekt. En dus hoe hard je trapt.
(...)
Het lijkt al een beetje te werken (de factor '-1000' in regel 84 heb ik even toegevoegd voor een toonbaar getal) maar nu komen de problemen uiteraard pas boven. De 'TorqueTare' en de 'TorqueFactor' boeien me nog niet zoveel, dat wordt een kwestie van meten en uitrekenen als de boel op de fiets gemonteerd is. Ijken. Andere dingen boeien mij wel. Zo blijkt mijn HX711 maar 10 signalen per seconden te geven. Da's wel erg weinig. Ik kan dat aanpassen naar 80, dat lijkt me beter. Maar ik krijg bij 150 toeren per minuut van het hoofdtandwiel (heb ik even als max ingeschat, is denk ik wat hoog) en 55 tanden op het tandwiel wel 137,5 pulsen per seconde van de inductieve sensor. Ik weet niet of dat teveel is, het lijkt me wel.

Zo, dat is waar ik nu ben, alle input is welkom. Liefst wel positief opbouwend Wink

Hugo

Leuk bedacht, en ik vraag me af hoe (goed) het gaat werken.
Een paar gedachten:
-Die 80kg max pedaaldruk lijkt me wat laag ingeschat, wie kan hinkelen kan als piekkracht toch ook wel 2x zijn eigen gewicht per been uitoefenen.
-De 150 rpm is mogelijk wat hoog. Sprekend voor mezelf, toen ik 18 was kon ik dat, nu heb ik grote moeite met 125 rpm.
-Maar nu mijn grootste vraagteken: mogelijk onderschat je de inertie van de (lange!) ketting nogal. Als ik op de Baron een sprintje doe, beweegt de ketting in meer richtingen dan Bram Moens zou goedkeuren Wink. En dat niet met 120 Hz ofzo, maar eerder met 4 Hz. Wellicht precies met het tempo van pedaalslagen, of misschien is de eigenfrequentie van de ketting zelf dominant, ik heb er nooit echt studie van gemaakt. Hoe dan ook, ik acht de kans aanwezig dat dat de waargenomen pulsfrequentie behoorlijk in de war gaat schoppen. Maar misschien werkt je middeling dan nog steeds prima. Om met Barry Stevens te spreken: Vooral doorgaan!
Airborne Valkyrie - Airborne Carpe Diem - Van Nicholas Euros - Koga Miyata FP Chromo - Optima Baron - Optima Orca - HP Gekko 20 FX
Antwoord }
Bedankt door: Willeke_IGKT
#32
Ik denk dat je het jezelf met die inductieve sensor te moeilijk maakt. Je hoeft je over koppel helemaal niet meer druk te maken: je meet de ketting kracht, en als je die vermenigvuldigd met de ketting snelheid dan ben je er al.

Met een simpel lichtsluisje kan je de door de ketting heen de schakels al tellen. Wellicht wel wat gevoelig voor vervuiling. Je kan ook een lichtsluisje zetten op een klein gaatje in de geleide rol. Voordeel is dat je zo de hele zaak bij elkaar houdt. Als je het netjes maakt krijg je zo een compacte unit die je op de plek van de bestaande rol zet.
Je hebt nog wel twee extra bronnen voor fouten: de ketting hoek wijzigt met de versnelling, en met de vering. De laatste kan je er denk ik wel uit middelen, maar de eerste is een systematische fout waar je even aan moet rekenen.

Goed bezig!
Fietser en knutselaar en eventjes niet in vorm. Roets, FlevoRacer en diverse (carbon) zelfbouwers voor 1 of 2 personen
Antwoord }
Bedankt door: Willeke_IGKT
#33
Magneetje in de geleide rol en een reed contact daar naast (waar kennen we dat van?) is nog simpeler.
Fietser en knutselaar en eventjes niet in vorm. Roets, FlevoRacer en diverse (carbon) zelfbouwers voor 1 of 2 personen
Antwoord }
Bedankt door: Willeke_IGKT
#34
(03-Mar-2024, 02:23 PM)Tijanus schreef: -De 150 rpm is mogelijk wat hoog. Sprekend voor mezelf, toen ik 18 was kon ik dat, nu heb ik grote moeite met 125 rpm.
Sterk afhankelijk van hoe je in elkaar zit. M'n hoogste piek ooit is 232 (toen was m'n derailleur stuk en had ik dus niets anders dan de 1e versnelling Big Grin ), 170 kan ik zeker nog wel halen en dan niet puur om zo snel mogelijk met m'n benen te draaien, gisteren niet echt gek gedaan en toch een keer 140 rpm gehaald.
In words of others,
Wisdom blooms, forums unite,
Quoted love takes flight.
Antwoord }
Bedankt door: Willeke_IGKT , Tijanus
#35
Eventjes gesorteerd op cadans:
[Afbeelding: cadans.jpg]
Registreer mijn activiteiten met meerdere devices. Dus heb even alleen individuele datums genomen. Zodat ik zeker geen dubbele heb. Maar ik wist dus al binnen een maandje al 144 rpm te trappen. Tongue
Geduld en respect voor de medemens is een schone zaak.
Antwoord }
Bedankt door: Willeke_IGKT , 365cycle
#36
Dank voor alle input. Ik hoop in het weekend weer een stapje te maken.

De tip van het lichtsluisje door de ketting ga ik proberen, ik heb nog wel zo'n IR-sensor-met-ontvanger moduletje liggen en ik kan wel iets 3D printen en op het uiteinde van de kettinggeleidebuis klemmen. Is inderdaad lekker dicht bij de andere sensor, makkelijk bekabelen en aansluiten. Magneetje in de geleiderol ben ik niet happig op, ik weet niet hoeveel slip er tussen ketting en geleiderol zit.

De hoekverschillen tussen de versnellingen zijn hoop ik weinig, ik ga het wel meten. En ik wil het ding in ieder geval ijken met mij erop, zodat de vering in de gemiddelde stand van gebruik staat.

Voor de rest heb ik uitgevonden dat de H711 versterker van de weegcel maar 10 waardes per seconde uitspuugd. Da's niet zo veel. Ik denk dat ik hem kan ombouwen naar 80, dat kan met dezelfde chip, moet alleen wat rommelen met het printplaatje en da's niet altijd even makkelijk met die kleine SMD componentjes. Borduurloep van moeders lenen, wellicht. En ik heb net de hardware interrupt functie in Arduino ontdekt, dus daar ga ik ook mee aan de slag om zoveel pulsen snel en goed te kunnen registreren. Genoeg te doen en zo weinig tijd...

Hugo
Antwoord }
Bedankt door: 365cycle , Willeke_IGKT
#37
(07-Mar-2024, 09:43 AM)HugoW1975 schreef: Voor de rest heb ik uitgevonden dat de H711 versterker van de weegcel maar 10 waardes per seconde uitspuugd. Da's niet zo veel. Ik denk dat ik hem kan ombouwen naar 80, dat kan met dezelfde chip, moet alleen wat rommelen met het printplaatje en da's niet altijd even makkelijk met die kleine SMD componentjes. Borduurloep van moeders lenen, wellicht. En ik heb net de hardware interrupt functie in Arduino ontdekt, dus daar ga ik ook mee aan de slag om zoveel pulsen snel en goed te kunnen registreren. Genoeg te doen en zo weinig tijd...

Hugo

Ik ben zo blij dat andere mensen hier iets van begrijpen  Big Grin  Oh wacht, ik weet wel wat een borduurloep is  Cool
Wim -de roetsende

Thys 209 Rowingbike  -  Milan SL MK7  -  M5 CHR*  -  M-SUB  -  VNR BT Freewheeler

Antwoord }
Bedankt door: martinR , Willeke_IGKT , Lig-hen
#38
Hugo, heb jij geen tandjes in je geleiderol?
Die met tandjes zullen geen slip hebben.
Voornaamste fiets(en): Carbon Strada 220  -  Whike  -  (Flevo bike, Flevo trike, beide alle wielen 20" en knik-kantel besturing, beide te koop maar hoeven niet weg.)
Antwoord }
Bedankt door:
#39
Dat is een goed idee om de interrupt van de Arduino te gebruiken. Succes!

Je kunt voor het uitlezen via een interrupt het beste een buffer gebruiken die je bij iedere interupt vult met een waarde en de buffer opschuift. Dan kun je in de normale loop de buffer uitlezen en je berekeningen doen. (En de buffer resetten). Dat doe ik voor de snelheidssensor in mijn fietscomputer. Zie mijn code ter inspiratie:

Interupt vult buffer:
https://github.com/JanBurp/VeloDashboard...ass.h#L514

Buffer uitlezen:
https://github.com/JanBurp/VeloDashboard...ass.h#L362

NB de links verwijzen naar de code van mijn fietscomputer in ontwikkeling. Neem gerust een kijkje. Later voeg ik beeldmateriaal toe zodat alles wat helderder wordt. Dan zal ik het ook actiever hier delen.
Quest 631
Antwoord }
Bedankt door: Willeke_IGKT , 365cycle
#40
Zo, ik ben weer een stukje verder. Verder achteruit, helaas, maar verder.

Zo ziet de set-up er nu uit:
[Afbeelding: 2TjlE6P.jpg]
De loadcel wordt ergens dicht bij het hoofdtandwiel op het frame gemaakt. Het tandwieltje op de loadcel drukt dan iets op de ketting en zo reageert de loadcel op de kracht op het pedaal. Een infraroodsensor telt de 'spaakjes' van dit tandwieltje. Met een hoofdtandwiel van 52 tanden, 13 tanden op het kleine tandwieltje en 6 spaken kom ik dan op 24 pulsen per omwenteling van het hoofdtandwiel. Dat makkelijker te verwerken dan 52. De HX711 versterker is aangepast van 10 naar 80 metingen per seconde.

De code ziet er nu zo uit:
Citaat:/*
16-03-2024 HugoW
This is the sketch for my Arduino based bicyle power gauge.
It uses an Arduino Nano, a TM1637 display, an inductive sensor on the bike's main sprocket
and a load cell with a wheel pressing on the power-part of the chain.
The harder you push on the pedal, the bigger the chain tension.
The sketch records the load cell value at each passing of a tooth and adds those numbers together.
After one full revolution, the accumulated number is devided by the number of teeth, is the average torque (with a bit of
calculating to get from load cell amplifier signal to real torque in Nm). The average torque multiplied by RPS(revolutions per second) is Watts.
*/

// Include libraries:
#include <Arduino.h>
#include <TM1637Display.h>
#include <HX711.h>

// Declare variables and pins:
// For torque measurement and power calculation:
const int LOADCELL_DOUT_PIN = 5;
const int LOADCELL_SCK_PIN = 6;
long torque;
HX711 scale;
int torqueSum;
int torqueTare;
int torqueFactor;
int wattage;
// For TM1637 display:
#define CLK 9
#define DIO 10
TM1637Display display = TM1637Display(CLK, DIO);
// For tooth pulse input:
int trigger = 2;
volatile int triggerCount;
int numberOfTriggers;
int mainGearTeeth;
int sprocketTeeth;
int sprocketSpokes;
// For cycle time:
int startTimer;
int stopTimer;
int cycleDuration;

void triggered()
{
torque = scale.read();                    // Read torque sensor.
torqueSum = (torqueSum + torque);        // Add torque to sum.
triggerCount = (triggerCount + 1);        // Raise counter by one.

if (triggerCount > numberOfTriggers)
{
  triggerCount = 0;                      // Reset trigger count to zero.
  stopTimer = millis();                        // Read millis at stop of cycle, determine duraton of cycle.
  cycleDuration = ((stopTimer - startTimer) / 1000);// Subtract starting value of millis to determine duraton of cycle.
  startTimer = millis();                      // Reset cycle.
    wattage = (((torqueSum / numberOfTriggers) - torqueTare) * torqueFactor / cycleDuration);// calculate wattage by dividing the torquesum by the triggerCount, subtracting the tare value and multiplying a factor to get real Newton meters, divide by cycle duration.
    torqueSum = 0;                        // reset torque sum to zero.
}
}

void setup()
{
// Declare pins and such:
Serial.begin(9600);
scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
pinMode(trigger, INPUT);
// Setup display:
display.clear();
display.setBrightness(7);
// Set changing values to zero
torqueSum = 0;
startTimer = 0;
stopTimer = 0;
display.showNumberDec(0, false);
// Set fixed values:
mainGearTeeth = 52;
sprocketTeeth = 13;
sprocketSpokes = 6;
numberOfTriggers = (mainGearTeeth / sprocketTeeth * sprocketSpokes);
torqueTare = 0;
torqueFactor = -0.001;
attachInterrupt (digitalPinToInterrupt(trigger), triggered, RISING);
}

void loop()
{
  display.showNumberDec(wattage, false);
  Serial.println(wattage);
  Serial.println(triggerCount);
  delay(500);
}

Maar werkt dus helaas niet. Ik weet nog niet waarom. Tips zijn welkom.

Hugo
Antwoord }
Bedankt door: Willeke_IGKT
#41
Kan je aangeven wat ie wel en wat ie niet doet?
Je deelt door 1000, gaat dat met int of met float?
Misschien even expliciet casten naar float.
Ik zou trouwens met zo hoog mogelijke cel de sensor uitlezen. En dan pas na een omwenteling alles middelen.
Antwoord }
Bedankt door: Willeke_IGKT
#42
Ik zou deze code:
Code:
// For cycle time:
int startTimer;
int stopTimer;
int cycleDuration;

Vervangen door:
Code:
// For cycle time:
unsigned long startTimer;
unsigned long stopTimer;
unsigned long cycleDuration;

Volgens mij mag je best wel de nauwkeurigheid hebben bij een tijd. En toen ik opzoek ging naar de timestamp, kwam ik dit tegen: https://www.arduino.cc/reference/en/lang...me/millis/

Hoe lang wil je maximaal fietsen? En bekijk de maximale waarde wat je in een variabel kan stoppen. Ik weet het niet meer precies welke Apollo vlucht??? Of andere vliegend door de mens ontworpen voertuig, maar er was eentje waarbij er een Integer is gebruikt die een te kleine maximale waarde had. En hierdoor is er een ongeluk gebeurd.
ook bij Boeing kennen ze er iets van:
Boeing 787 Dreamliners contain a potentially catastrophic software bug | Ars Technica
En eigenlijk was het millennium probleem een soort gelijke. De maximale waarde van de datum was minder dan de datum van het nieuwe jaar. Dus zonder ingrijpen zou het getal weer 0 zijn en dit bracht de datum terug bij de start bij tellen.
Geduld en respect voor de medemens is een schone zaak.
Antwoord }
Bedankt door: Willeke_IGKT
#43
Als ik het zo zie bereken je in de trigger functie alles. Het idee is dat een trigger functie héél weinig tijd mag kosten dus daar doe je echt niets anders dan de buffer vullen en ophogen.

In de normale loop lees je de buffer in z’n geheel uit en reken je uit wat je maar wilt. En reset de buffer.

Geen idee of dat in dit geval helpt. Maar iig ‘best practice’.

Succes!

Oh en ik zie nu ook dat je ‘millis()’ aanroept in de trigger functie. Dat gaat zeker niet werken (ik weet even niet mee waarom, maar timers in trigger functies gaan niet samen). En dat deel kun je dus het best in de normale loop doen.
Quest 631
Antwoord }
Bedankt door: Willeke_IGKT
#44
Leuk, al die ICT-kennis bij ligfietsers.
rij zowel onderstuur als aero-stuur
Antwoord }
Bedankt door: Willeke_IGKT , Hardloper
#45
Kun je trouwens ook wat doen met de constructor en de variabele?

Zelf nooit wat met de Arduino geprogrammeerd , maar bekijken van code is wel mijn vak gebied.
Geduld en respect voor de medemens is een schone zaak.
Antwoord }
Bedankt door: Willeke_IGKT
#46
@LigfietsWilsum; dank voor je reactie. Ik heb weer wat aangepast, zie hieronder. Ik heb geen idee wat 'casten naar float' betekent, en google helpt me niet heel veel. Kan jij het uitleggen? Ik heb nu torqueFactor maar een float genoemd. Leek me leuk...

@Hardloper; dank voor je reactie. Ik heb het aangepast, snap ook een beetje waarom. Ik lees dat de millistimer 52 dagen blijft tellen, als ik 52 dagen nonstop fiets dan kijk ik tegen die tijd wel naar een oplossing. Tot dan denk ik dat ik vaker dan eens in de 52 dagen het ding herstart.

@JanBurp; dank voor je reactie. Ik snap wat je bedoelt, heb de code aangepast. Ik snap nog niet waarom ik iets in een buffer moet plaatsen, en ook niet hoe. Wel valt me op dat jij in je eigen voorbeeld in je eerste post in dit topic wel Millis() gebruikt in je interrupt (eerste link, regel 516). Waarom mag jij dat wel en ik dat niet? Wink

Code:
Citaat:/*
16-03-2024 HugoW
This is the sketch for my Arduino based bicyle power gauge.
It uses an Arduino Nano, a TM1637 display, an inductive sensor on the bike's main sprocket
and a load cell with a wheel pressing on the power-part of the chain.
The harder you push on the pedal, the bigger the chain tension.
The sketch records the load cell value at each passing of a tooth and adds those numbers together.
After one full revolution, the accumulated number is devided by the number of teeth, is the average torque (with a bit of
calculating to get from load cell amplifier signal to real torque in Nm). The average torque multiplied by RPS(revolutions per second) is Watts.
*/

// Include libraries:
#include <Arduino.h>
#include <TM1637Display.h>
#include <HX711.h>

// Declare variables and pins:
// For torque measurement and power calculation:
const int LOADCELL_DOUT_PIN = 5;
const int LOADCELL_SCK_PIN = 6;
long torque;
HX711 scale;
int torqueSum;
int torqueTare;
float torqueFactor;
int wattage;
// For TM1637 display:
#define CLK 9
#define DIO 10
TM1637Display display = TM1637Display(CLK, DIO);
// For tooth pulse input:
volatile int trigger = 2;
volatile int triggerState;
int triggerCount;
int numberOfTriggers;
int mainGearTeeth;
int sprocketTeeth;
int sprocketSpokes;
// For cycle time:
unsigned long startTimer;
unsigned long stopTimer;
unsigned long cycleDuration;

void triggered()
{
triggerState = 1; // Set triggerState high, so the loop knows what to do
}


void setup()
{
// Declare pins and such:
Serial.begin(9600);
scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
pinMode(trigger, INPUT);
// Setup display:
display.clear();
display.setBrightness(7);
// Set changing values to zero
torqueSum = 0;
startTimer = 0;
stopTimer = 0;
triggerState = 0;
triggerCount = 0;
display.showNumberDec(0, false);
// Set fixed values:
mainGearTeeth = 52;
sprocketTeeth = 13;
sprocketSpokes = 6;
numberOfTriggers = (mainGearTeeth / sprocketTeeth * sprocketSpokes);
torqueTare = 0;
torqueFactor = -0.001;
attachInterrupt (digitalPinToInterrupt(trigger), triggered, RISING);
}

void loop()
{

if ((triggerState == 1) && (triggerCount < numberOfTriggers))
{
torque = scale.read(); // Read torque sensor.
torqueSum = (torqueSum + torque); // Add torque to sum.
triggerCount = (triggerCount + 1); // Raise counter by one.
triggerState = 0; // Reset trigger state.
}

if ((triggerState == 1) && (triggerCount >= numberOfTriggers))
{
torque = scale.read(); // Read torque sensor.
torqueSum = (torqueSum + torque); // Add torque to sum.
triggerCount = (triggerCount + 1); // Raise counter by one.
triggerState = 0; // Reset trigger state.
triggerCount = 0; // Reset trigger count to zero.
stopTimer = millis(); // Read millis at stop of cycle, determine duraton of cycle.
cycleDuration = ((stopTimer - startTimer) / 1000);// Subtract starting value of millis to determine duraton of cycle.
startTimer = millis(); // Reset cycle.
wattage = (((torqueSum / numberOfTriggers) - torqueTare) * torqueFactor / cycleDuration);// calculate wattage by dividing the torquesum by the triggerCount, subtracting the tare value and multiplying a factor to get real Newton meters, divide by cycle duration.
torqueSum = 0; // reset torque sum to zero.
}

display.showNumberDec(wattage, false);
Serial.println(triggerState);
delay(250);
}

Helaas reageert triggerState nu helemaal niet op de trigger. Iets met Jans buffer, gok ik.

Hugo
Antwoord }
Bedankt door: Willeke_IGKT
#47
Die delay(500) kan ook de schuldige zijn. Delay stop tijdelijk program executie en legt  veel plat. Interrupts lopen wel door, maar ik denk dat het rekenwerk stopt.
Je kan beter milis() voor de timing gebruiken, net zoals je dat voor de meting doet.

En alles behalve de essentie uit de interrupt routines halen is ook belangrijk (maar dat heb je al gedaan toen ik dit schreef), want zolang je in een interrupt routine bezig bent komen er geen andere interrupts binnen. Ook serial is volgens mij op interrupt basis, bij Arduino gebeurt er vaak meer dan je denkt. Daarom programmeer ik vaak liever dichter op de hardware.

Ik ben zelf geen voorstander van het gebruik van floats, het kost veel rekentijd en de precisie is beperkt. Rekenen kan ook prima met integers of longs als je ze als fixed point representatie gebruikt, bijvoorbeeld 1000=1. Dat scheelt heel veel tijd.
Fietser en knutselaar en eventjes niet in vorm. Roets, FlevoRacer en diverse (carbon) zelfbouwers voor 1 of 2 personen
Antwoord }
Bedankt door: Willeke_IGKT
#48
Die delay is zeker niet goed, maar gebruik ik nu voor het uitlezen. Ik draai het wieltje langzaam met de hand, dus alles hoeft nu niet snel. Ik zie zo wel beter wat er gebeurt. En dan zie ik dat de triggerCount bij iedere loop wordt opgehoogd, tot 23. Dan twee keer 0 en dan weer 1, 2, 3 .... 23 enz. Of ik de trigger activeer of niet maakt niet uit. En terwijl ik triggerState in de setup op '0' zet en hij pas iets zou moeten doen als triggerState '1' is. En da's raar...

Ik wissel de inhoud van de serial.println regelmatig om te kijken wat er gebeurt.

[EDIT]
Het doortellen heb ik gefikst, was een tiepvaud. Er stond maar '=' in het if-statement, moest een '==' zijn. Hij telt nu wel, maar ik zie dat hij vaak per spaak van het kleine tandwieltje meerdere keren telt. Drie of vier erbij in de triggerCount is geen uitzondering. Ik hoopte dat die sensor een netjes stabiele puls zou uitzenden. Kennelijk moet ik daar iets aan debouncen, jammer. Kost weer tijd, vrees ik.
[/EDIT]

Hugo
Antwoord }
Bedankt door: Willeke_IGKT
#49
Als je een int deelt, dan wordt het niet automatisch een float, dat is afhankelijk van het type in de vergelijking.

float f;
int x = 900;
int y = 1000;
f = x /y;
dan is f dus 0, want er gaat in ints gerekend worden, dan pas naar float.
900 / 1000 = 0
1100 / 1000 = 1
casten is het gewenste type er voor zetten:
float f;
int x = 900;
int y = 1000;
f = (float) x/ (float) y
f is nu 0.9.

print statements kunnen de boel ook verzieken. die kunnen de heleboel ophouden,
ook is het beter de snelheid van de seriele interface veel hoger te zetten, 115200. Dan wordt het oponthoud al een stuk minder.

Zet je displayaansturing ook maar even uit, die kan ook teveel tijd kosten...
(Helemaal, dus ook niet initialiseren.)

Als het kan (PC en Arduino), dan de seriele poort zelfs nog hoger zetten. Kijk maar wat het max is. Ik draai hier zelf op > 1Mbaud. (Geen Arduino overigens, maar STM32H750)
Antwoord }
Bedankt door: Willeke_IGKT
#50
@HugoW1975 ken jij ook iets van Python / Java of C(++) voor de computer?
Wat je kan overwegen is om een applicatie te schrijven als desktop (console) applicatie. Hierna ga je op basis van een array (achtige structuur) door heel je lijst en die array bevat dan de fictieve invoer van je sensor. Hierna ga je kijken of heel de logica werkt. Waarna je het gaat herschrijven voor de Arduino. Misschien ontwikkelt dat wel wat makkelijker.

(07-Mar-2024, 10:20 AM)Wim -de roetsende schreef: Ik ben zo blij dat andere mensen hier iets van begrijpen  Big Grin  Oh wacht, ik weet wel wat een borduurloep is  Cool

En ik ben blij dat jij de kinderen weer weet les te geven. Want dat zou voor mij helemaal niks zijn.
Geduld en respect voor de medemens is een schone zaak.
Antwoord }
#51
Ik snap niet helemaal wat je nu ziet. Als je teller op loopt dan moet triggerstate hoog zijn. Weet je zeker dat het signaal op pin2 strak is? Als daar gekke dingen gebeuren (beetje ruis bijvoorbeeld) dan wordt je isr getriggerd.
Ik zou die delay echt vervangen door millis, want je hebt geen idee wat er gebeurd als er tijdens de delay een trigger komt, dat is ook in de documentatie niet echt lekker gedefinieerd.

Uitleg over waarom je geen millis() mag gebruiken in een isr: tijdens een isr zijn andere interrupts disabled, want de isr heeft voorrang op alles. En millis() gebruikt zelf weer een isr , dus dat bijt elkaar.

Dat is het grote nadeel van arduino: het is maar beperkt duidelijk wat de code doet en welke resources ( bv timers) daarvoor gebruikt worden. Als het simpel is komt het goed, wordt het ingewikkelder dan kan je klem lopen. Dit is gelukkig nog simpel.
Fietser en knutselaar en eventjes niet in vorm. Roets, FlevoRacer en diverse (carbon) zelfbouwers voor 1 of 2 personen
Antwoord }
Bedankt door: Willeke_IGKT
#52
Dank allemaal voor de input.

@LigfietsWillsum; ik denk dat ik het een beetje snap, maar ik denk dat het niet het probleem is. In principe werk ik met hele getallen, zonder komma, totdat ik met de wattageberekening aan de slag ga. En dan wil ik geen cijfers achter de komma weten.

@Hardloper; ik weet helemaal niks van programmeren. Ik kopieer en modificeer vaak codes om eigen projecten te maken. Dus wat je voorstelt klinkt logisch, maar voor mij veel te ver. En zo complex is het ook weer niet, wat ik nu doe. Ik heb wel net gelezen dat je in AutoDesk TinkerCAD simulaties kan maken, dat ga ik voor de lol eens proberen. Ik gebruik voor eenvoudige 3D ontwerpen wel vaker TinkerCAD, ik kende deze toepassing nog niet.

@Merijn; het signaal op pin 2 is inderdaad een groot probleem, ik weet nog niet waar dat in zit. Het lijkt erop dat de sensor even stottert als hij van staat wisselt. Niet de bedoeling. Ik denk dat ik snap waarom je geen millis() functie in je isr mag gebruiken, ik vraag me daarom des te meer af waarom / hoe JanBurp dat dan wel (succesvol?) doet in de code die hij linkte.

Gelukkig heb ik een groot deel van de nacht wakkergelegen en dus na kunnen denken. Ik heb een simpele denkfout gevonden. In deze nieuwe code heb ik in de setup de tareerwaarde laten bepalen. Dat is op zich goed, maar heeft wel tot gevolg dat de uit te voeren Watt waarde rond de nul zal zijn, zolang ik de cel niet belast. De weegcelwaarde fluctueert wel een beetje, ook 'stationair', maar door die factor -0,001 (die ik erin gezet had om die grote waardes te temmen / af te ronden) wordt nu alles naar nul afgerond. Ik heb die factor nu aangepast naar -0,1 en nu heb ik waardes die verschijnen. Jeee! Die factor zal ongetwijfeld weer veranderen als ik de boel ga ijken, maar voor nu is de werking in ieder geval bewezen.

Nu alleen nog de triggersensor stabiel krijgen.

Hugo
Antwoord }
Bedankt door: Willeke_IGKT


Ga naar locatie:


Gebruikers die dit topic lezen: 1 gast(en)
Welkom
Je moet jezelf aanmelden voor je een bericht kunt plaatsen.

Gebruikersnaam:


Wachtwoord:





Nieuwe berichten
Vandaag ben ik niet blij omdat.....
Later we vooral er n...Hardloper — 02:37 PM
Velion / Code naam: VM45
10 min langer de ...Hardloper — 02:35 PM
Zelfbouw voorwiel aangedreven ligfiets ...
Lang leve ducttape...GHOOGEN — 02:30 PM
Quest xs nr 13
De Milan is een wa...Gideonaut — 01:12 PM
Zelfbouw voorwiel aangedreven ligfiets ...
Oh, je kan je zadel ...LigfietsWilsum — 01:11 PM
Zelfbouw voorwiel aangedreven ligfiets ...
Lang leve ducttape. ...Fietsbennie — 12:40 PM
Zelfbouw voorwiel aangedreven ligfiets ...
Met het kleine ac...GHOOGEN — 12:34 PM
Quest xs nr 13
En toch zul je er ...Wim -de roetsende — 12:06 PM
Utrechtse Heuvelrug - Zuid Limburg
Mooie foto's Martin....Fietsbennie — 11:17 AM
Quest xs nr 13
Als ik iets te koo...melle z — 10:16 AM
Vandaag ben ik niet blij omdat.....
Mijn gevoel zegt dat...Wim -de roetsende — 09:44 AM
Quest xs nr 13
Ook speelt missc...Wim -de roetsende — 09:38 AM
Zelfbouw voorwiel aangedreven ligfiets ...
Ik kan er mee ri...Wim -de roetsende — 09:10 AM
Zelfbouw voorwiel aangedreven ligfiets ...
Mijn Flevo ervarin...GHOOGEN — 12:56 AM
Velion / Code naam: VM45
Een multi programm...365cycle — 11:37 PM
Quest xs nr 13
De Milan is een wat ...Jeroen S — 11:28 PM
Velion / Code naam: VM45
Een multi programmeu...Tom Fekkes — 11:23 PM