Snelheidsmeter voor fiets

hoi wij willen met een ardino en een lcd schermpje een fietssnelheids meter maken. wij gebruiken een reedcontact en als het magneetje er langs komt word die reedcontact geactiveer. de reedcontact kom op het frame te zitten en de magneet op het velg. de via de rotatie de hoeveelheid dat de reedcontact word geactiveerd moet de snelheids in kilometer per uur aangeven op het lcd schermpje. wij willen graag een kloppende code voor liquidcristal_i2c

Kunnen jullie ons mischien helpen? wij komen er niet uit.

Welkom.

Vertel eens waar je mee vast zit.

Ik denk niet dat het gaat werken als zowel het contact als de magneet op het frame zitten :wink:

je komt er niet uit staat er.
Welke code heb je al geprobeerd?
Wat is je berekening voor het pulsje naar kilometer/uur?

hahaha dat is fout 1:) (typ fout)

Ja, wij zijn redelijk nieuwe met codes programmeren en hebben een paar codes van internet gepakt en beetje aangepast naar hoe het zou moeten werken, maar dat doet het niet. Hoe zouden jullie dit aanpakken?

Mvg, bedankt voor de reacties.

Dat is een open deur :wink: Wat je op het internet gevonden hebt bestuderen en begrijpen. Daarna combineren.

Als je je programma laat zien kan iemand misschien zien wat er fout gaat. De gemakkelijkste manier om op het forum een programma te plaatsen is

  1. In de IDE
    • Tools / Autoformat (Hulpmiddelen / Automatische opmaak); dit lijnt je programma netjes uit.
    • Edit / Copy for forum (Bewerken / Kopieren voor forum); dit plaatst een kopie van je programma in het kladblok.
  2. Het gekopieerde programma in een nieuw bericht plakken.

Dat is altijd een vage beschrijving. Kun je aangeven wat je verwacht dat je programma doet en wat het daadwerkelijk doet?

#include <Arduino.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
 
LiquidCrystal_I2C lcd(0x27, 16, 2);
 
const int reedSensorPin = 4;
const int contrastValue = 200; 
 
unsigned long startTime = 0;
unsigned long elapsedTime = 0;
unsigned long lastActivityTime = 0;
int count = 0;
bool counting = false;
 

void startCounting();
void stopCounting();
 
void setup() {
  lcd.init();
  lcd.backlight();
  lcd.setContrast(contrastValue); 
  lcd.setCursor(0,0);

  
  pinMode(reedSensorPin, INPUT_PULLUP);
}
 
void loop() {

  
  
  if (digitalRead(reedSensorPin) == LOW) {
    if (!counting) {
      startCounting();
      counting = true;
    }
    lastActivityTime = millis();
    count++;
    delay(100); 
  } else {
   
    if (counting && (millis() - lastActivityTime > 3000)) {
      stopCounting();
      counting = false;
    }
  }
  
}
 
void startCounting() {
  startTime = millis();
  count = 0;
}
 
void stopCounting() {
  elapsedTime = millis() - startTime;
  
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Elapsed Time: ");
  lcd.print(elapsedTime / 1000);
  
  lcd.setCursor(0, 1);
  lcd.print("Count: ");
}

Hierbij onze code. Hopelijk zien jullie onze fout. Groetjes

Je gebruikt millis() en vervolgens gebruik je ook een delay(100).Dat zijn zaken die niet met elkaar verenigbaar zijn. Een delay zorgt ervoor dat de controler niets doet gedurende de delay. Daarnaast wil je een afstand in km/uur hebben, ik zie nergens de berekening van omtrek en pulsjes naar km

Geef een goede beschrijving wat "maar dat doet het niet" betekent. Het doet iets (misschien niet zichtbaar).

Heb je al wat korte test programmas geschreven?

  1. Vergeet even dat er een LCD is en test je sensor met Serial prints.
  2. Vergeet even dat er een sensor is en test de LCD met een voorbeeld van de LiquidCrystal_I2C bibliotheek.

Je programma lijkt te tellen zolang the sensor LOW is en een gegeven tijd niet verstreken is. Dat zal een maximum van 10 counts per seconde zijn ten gevolge van de delay(). Kun je de logica van je programma beschrijven?

Ik vermoed dat je programma een stuk beter wordt als je neergaande flanken telt; kijk eens naar het state change detection voorbeeld in de IDE.

hallo, wij hebben de sensor los al getest met een led. Als het magneetje dicht genoeg langs de sensor kom springt het lampje aan dus dat werk al. Ook hebben wij de lcd getest en die werkte ook. kortom het apparatuur werkt los van elkaar goed.

Kijk eens wat hier uitkomt op de seriele monitor. Het zou je een idee moeten geven hoeveel pulsen je krijgt per seconde (gebaseerd op de millis() die geprint wordt). Vanwege de korte delay() kun je een maximum van honderd pulsen per seconde detecteren.

// reed contact
const int reedSensorPin = 4;

// laatste lezing
uint8_t prevReading = HIGH;

void setup()
{
  Serial.begin(115200);
  pinMode(reedSensorPin, INPUT_PULLUP);
}

void loop()
{
  // huidige lezing
  uint8_t currReading = digitalRead(reedSensorPin);

  // als er een verschil is en de huidige lezing is LOW
  if (currReading == LOW && prevReading == HIGH)
  {
    Serial.print(millis());
    Serial.println(F(" > Magneet gedetecteerd"));
  }

  // huidige lezing onthouden.
  prevReading = currReading;

  // korte ontdender
  delay(10);
}

Ik gebruik in het algemeen uint8_t in plaats van byte en dat is groot genoeg om het resultaat van een digitalRead() in op te slaan.

Ik vermoed dat je altijd moet ontdenderen en dat zal het aantal pulsen dat je kunt detecteren beperken. De makkelijkste manier om dat aan te passen is om de sensor en de magneet wat verder van de as van het fiets wiel te plaatsen; het alternatief is om te ontdenderen in hardware.

Je kunt het programma verder uitbouwen en een teller toevoegen en je millis() gebaseerde tijdmeting.

PS
Testen met langzaam draaiend fiets wiel en snel draaiend fiets wiel en kijken wat de mogelijkheden zijn met bovenstaand programma.

Ster, 100 pulsjes per seconde bij een radius van 15 cm zou een verplaatsing zijn van ongeveer100 meter per seconde zijnde 6km per minuut als ik me niet vergis. Lijkt mij een onhaalbare snelheid op een fietsje

Heel erg bedankt! ja ik heb inderdaad millis gebruikt. oorspronkelijk wilde ik eigenlijk kilometer per uur, echter wist ik niet hoe dat er in kon zetten. Maar dit is nogsteeds wel het doel. Ik zal uw codes eerst even proberen.

even wiskunde knobbel aanzetten en uitrekenen hoeveel afstand er per puls gegeven wordt en dan kun je de tijd per puls uitrekenen , denk wel dat je niet alle pulsen meet als het te snel gaat dan moet je iets doen met een ISR op pin 2

Shooter, het zal bij normale fietswielen altijd minder zijn dan 20 pulsjes per seconde, waarschijnlijk zelfs minder dan 12. Daar hoef je geen interrupt voor te gebruiken maar een delay zou ik daar zeker niet bij gebruiken omdat je dan een pulsje over zou kunnen slaan en dat beïnvloed de uit te rekenen snelheid wel enorm.

hallo, we komen er nogsteeds niet uit nu hebben we besloten om eerste even een code te maken die de pulsen telt. Hoe werken we dit uit naar km/H

#include <Arduino.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);

const int reedSensorPin = 4;
const int contrastValue = 200;

unsigned long startTime = 0;
unsigned long elapsedTime = 0;
unsigned long lastActivityTime = 0;
int count = 0;
int aantal = 0;
bool counting = false;

int state = 0;

void startCounting();
void stopCounting();

void setup() {
lcd.init();
lcd.backlight();
lcd.setContrast(contrastValue);
lcd.setCursor(0,0);
lcd.print("Ready");
pinMode(reedSensorPin, INPUT_PULLUP);

lcd.setCursor(0,0);
lcd.print("count: ");
lcd.print(count);
}

void loop() {

if (digitalRead(reedSensorPin) == LOW && state == 1)
{
state = 0;
//count = 0;
count++;
lcd.setCursor(7,0);
count++;
lcd.print(count);

delay(10);
  

/*
if (count > 0) {
  count = +0;
}
*/

}
if (digitalRead(reedSensorPin) == HIGH && state == 0)
{
state = 1;
//count = +1;
delay(10);
}

switch(state)
{
case 0:
{

  break;
}
case 1:
{
  break;
}
default:
{
  break;
}

}

}

void startCounting() {
startTime = millis();
count = 0;
}

void stopCounting() {
elapsedTime = millis() - startTime;

lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Elapsed Time: ");
lcd.print(elapsedTime /1000);

lcd.setCursor(0, 1);
lcd.print("Snelheid:");
lcd.print(count /100);
}

Wat is er gebeurd met het gebruik van code tags? Terwijl je het programma van je vorige post even van code tags voorziet zodat het wat gemakkelijker te lezen en te copieren is en de forum software het niet ziet als instructies om de tekst te formatteren,zal ik er even over nadenken.

Laten we even stellen dat je 2 pulsen per seconde krijgt; iedere puls is een omwenteling van het wiel. Vermenigvuldig dat met de omtrek van je wiel.

Een omwenteling van een wiel met een diameter van 60 cm is pi * 60 = 188 cm, dus zijn twee pulsen een snelheid van 3.76 meter / seconde.

Er zitten 3600 seconden in een uur dus je vermenigvuldigt de snelheid in m / s met 3600 en je hebt de snelheid in meters / uur. Even delen door 1000 om van meters naar km te gaan en je hebt de snelheid in km / u.

De snelle omrekening van meters / seconde naar kilometers / uur is een factor 3.6 (dat is die 3600 / 1000). Dus vermenigvuldig je de meters / seconde met 3.6 om op kilometers / uur uit te komen.

Dit is onze code geworden en deze lijkt perfect te werken in combinatie met de reed sensor en de specifieke diameter van de velg.

#include <Arduino.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
 
LiquidCrystal_I2C lcd(0x27, 16, 2);
 
const int reedSensorPin = 4;
const int contrastValue = 200; 
 
unsigned long startTime = 0;
unsigned long elapsedTime = 0;
unsigned long lastActivityTime = 0;
int count = 0;
float speed = 0;
bool counting = false;
 
int state = 0;

void startCounting();
void stopCounting();
 
void setup() {
  lcd.init();
  lcd.backlight();
  lcd.setContrast(contrastValue); 
  lcd.setCursor(0,0);
  lcd.print("Ready");
  pinMode(reedSensorPin, INPUT_PULLUP);

  lcd.setCursor(0,0);
  lcd.print("speed: ");
  lcd.print(count);

  Serial.begin(9600);
  startTime = millis();
}
 
void loop() {
  
  if (digitalRead(reedSensorPin) == LOW && state == 1) 
  {
    state = 0;
    //count = 0;
    count++;
    
    delay(10);
      
  
    /*
    if (count > 0) {
      count = +0;
    }
    */
  }
  if (digitalRead(reedSensorPin) == HIGH && state == 0) 
  {
    state = 1;
    //count = +1;
    delay(10);
  }

  switch(state)
  {
    case 0:
    {

      break;
    }
    case 1:
    {
      break;
    }
    default:
    {
      break;
    }
  }


  elapsedTime = millis() - startTime; 
  if(elapsedTime >= 1000)
  {
    //Serial.print(elapsedTime);
    //Serial.print("  ");
    //Serial.println(count);
    speed = count*3500 / (elapsedTime);
    count = 0;
    startTime = millis();
    lcd.setCursor(7,0);
    //count++;
    lcd.print(speed);

    lcd.setCursor(12,0);
    lcd.print("km/h");
  
  }

}

`> Blokcitaat`

Voor de snelheidsmeter hadden wij nog een toestands diagram gemaakt waaruit we verder konden bouwen.