Probleem met Hall Sensor

Hallo,

Ik heb een probleem. Ik heb op mijn oldtimer een andere carburatuer gebouwd, waardoor zowel mijn verbruik als mijn vermogen is gestegen. Omdit te monitoren heb ik een soort computertje gemaakt met verschillende menu's waar ik het verbruik kan monitoren.

Ik heb de gehele proefopstelling werkend gekregen op mijn bureau, alleen met een willekeurige hall sensor en een willekeurige magneet. Op een beurs heb ik een speciale schijf (duur) aangeschaft die exact om mijn aandrijfas heen past. Het probleem is alleen dat deze is uitgerust met allemaal noordpolen gericht naar de buitenzijde. De hall sensor die ik gebruikte had een Npool nodig om een High te geven en had vervolgens een Z-pool nodig om te resetten.

Dus ik heb de Honeywell SS495A aangeschaft. Alleen toen begonnen de problemen. Deze sensor geeft een waarde van rond de 500 wanneer er geen magneet in de buurt is. Hij zakt richting de 0 wanneer er een noordpool langskomt en stijgt richting de 1023 wanneer de z-pool langskomt.

Alleen nu reageert hij ook op mijn flowmeter (telt ook pulsen) en wanneer mijn flowmeter pulsen telt, dan telt de hallsensor deze er ook bij op. Ook telt de hall sensor willekeurig status veranderingen.

Hieronder heb ik een voorbeeldcode weergegeven, waarvan ik uit ga:
Ik heb al geprobeer Raising in falling and low te veranderen maar dit helpt niet.

float rpmHV;
 float flowHV;
 float rpmTRV;
 float flowTRV;
 float rpmTAV;
 float flowTAV;


void setup()
{
  attachInterrupt(1, rpm_fun, RISING);
  rpmHV = 0;
  rpmTRV = 0;
  rpmTAV = 0;

  attachInterrupt(0, flow_fun, RISING);
  flowHV= 0;
  flowTRV= 0;
  flowTAV= 0;
}


void rpm_fun()
{
  rpmHV++;
  rpmTRV++;
  rpmTAV++;

}

void flow_fun()
{
  flowHV++;
  flowTRV++;
  flowTAV++;
}

Ook heb ik zowel bij de hall-sensor als de flowmeter een 100k weerstand tussen de 5V en de output geplaatst.

Alle suggesties zijn zeer welkom!

370 keer gelezen, maar niemand een idee of gedachte?

Nald:
370 keer gelezen, maar niemand een idee of gedachte?

Ik heb nog niet gereageerd omdat het verhaal niet duidelijk is voor mijn. Ook is de code niet volledig. Je geeft enkel de setup en de code van de interrupts. Daarmee kan ik niet veel.
Daarbij komt dat de code ook raar over komt. Bijvoorbeeld: Waarom gebruik je float en niet long? Waarom gebruik je 3 variabelen wanneer je bij alle drie ++ doet bij een pulse.
Ik ken al dien sensors niet maar als je de pulse meet van 2 sensors vraag ik mij af waarom dat je denkt dat je een software probleem hebt en geen hardware.

Met vriendelijke groet
Jantje

Kijk dat is tenminste een reactie waar ik wat mee kan.

Hierbij allereerst een versimpelde code. Met een simpele test setup. Ik gebruik float omdat ik berekeningen maak met de waardes om zo een kommagetal te creëeren uit ervaring ben ik erachtergekomen dat de berekeningen niet werken als ik unsigned long gebruikt.

Ik gebruik 3 variabelen omdat zo op verschillende tijden gereset worden. 1 word gereset per 500 ms, de andere wordt gereset bij een tripreset en de andere wordt gereset bij een tankbeurt.

Ik weet niet of ik een software probleem heb, daarom ben ik hier.

volatile float rpmHV;
volatile float flowHV;
volatile float rpmTRV;
volatile float flowTRV;
volatile float rpmTAV;
volatile float flowTAV;

int HVmillis=500;
unsigned long millishv;

void setup()
{
    attachInterrupt(1, rpm_fun, RISING);
  rpmHV = 0;
  rpmTRV = 0;
  rpmTAV = 0;

  attachInterrupt(0, flow_fun, RISING);
  flowHV= 0;
  flowTRV= 0;
  flowTAV= 0;

  Serial.begin(9600);
  
}

void loop(){
  if ((long)(millis()-millishv) >=0){
  Serial.print("rpmcount: "); 
  Serial.println(rpmHV);
  Serial.print("flowcount: ");
  Serial.println(flowHV);
  millishv=millis() + HVmillis;
  }}
  
  void rpm_fun()
{
  rpmHV++;
  rpmTRV++;
  rpmTAV++;

}

void flow_fun()
{
  flowHV++;
  flowTRV++;
  flowTAV++;
}

De compleete code is te groot om hier te posten.

Ik zou de sectie http://arduino.cc/en/Reference/AttachInterrupt eens goed lezen.
Ik weet niet of het met je probleem te maken heeft maar je gebruikt interrupts niet zoals je zou moeten.
Meer specifiek het gebruik van volatile en noInterrupts(); interrupts();

Om te weten of je een hardware of software probleem hebt kan je best een klein en simpele sketch schrijven om uit te maken wat je binnenkrijgt.

Met vriendelijke groet.
jantje

als ik je link doorlees, dan snap ik niet waarom ik ze verkeerd gebruik. Hoezo gebruik ik ze verkeerd dan?

De arduino moet immers altijd pulsen tellen, als ik er 1 mis dan kloppen mijn metingen niet.

De geposte code is toch een simpele sketch? ik krijg nu immers beide sensoren binnen. Het probleem is dat wanneer de flowmeter een meting uitvoert, om de een of andere reden de hall sensor dit ook registreert.

Via analoge metingen weet ik dat ik een analoge waarde krijg fluctuerend (507-511) als er geen magneet in de buurt komt, en dat hij richting de 0 gaat als er een magneet langskomt.

nogmaals dit probleem komt alleen voor als ik de latch hall sensor vervangt door de lineare hall sensor.

Nald:
als ik je link doorlees, dan snap ik niet waarom ik ze verkeerd gebruik. Hoezo gebruik ik ze verkeerd dan?

De arduino moet immers altijd pulsen tellen, als ik er 1 mis dan kloppen mijn metingen niet.

Gebriuk de interrupt om pulsen te tellen (in een volatile unsigned long)
Copieer die volatile long tussen noInterrupts(); en Interrupts(); naar een variabele die niet door de interrupt wordt gebruikt.
Doe je berekeningen op basis van die variabele.

quote author=Nald link=topic=130085.msg981595#msg981595 date=1351956458]
De geposte code is toch een simpele sketch? ik krijg nu immers beide sensoren binnen. Het probleem is dat wanneer de flowmeter een meting uitvoert, om de een of andere reden de hall sensor dit ook registreert.

Via analoge metingen weet ik dat ik een analoge waarde krijg fluctuerend (507-511) als er geen magneet in de buurt komt, en dat hij richting de 0 gaat als er een magneet langskomt.

nogmaals dit probleem komt alleen voor als ik de latch hall sensor vervangt door de lineare hall sensor.
[/quote]
Zonder dat ik er iets van je sensoren afweet lijkt me dat een "latch hall sensor" zich anders zal gedragen dan een "lineare hall sensor". Je zal dan ook andere hardware en/of software nodig hebben als je de een door de andere wilt vervangen.

Met vriendelijke groet
Jantje

dank je voor de tip, ik zal kijken of ik dit ka implementeren.

Maar heb je een idee welke code ik moet gebruiken voor de hall-sensor. Ik kan in de loop iets zetten met een buttonstate verandering. Maar dan ben ik bang dat de code te langzaam is en ik metingen mis.

370 keer gelezen, maar niemand een idee of gedachte?

al op de Engelstalige thread geantwoord voordat deze thread gestart is.

@ rob waarvoor dank, maar ik ben er nog steeds niet uit. Heb jij misschien een idee?

ja, maar ik zie geen bijgewerkte (laatste versie) code van jou en eventuele output nav de opmerkingen die gemaakt zijn.
Dus ik kan niet zien hoever je nu bent en waar mogelijk nog problemen zitten.

@ Rob, ik heb mijn code niet aangepast omdat ik geen output heb gekregen die mij verder heeft geholpen. Alle verbetercodes die in detail anders waren dan mijn huidige broncode heb ik toegepast maar allemaal gaven ze geen ander resultaat.

tevens heb ik aan jou een vraag gesteld waarom je iets anders noteerde dan ik, omdat ik het wil begrijpen hier heb jij nog steeds niet op geantwoord.

Why do you write: #define INTERVAL 500UL what is the difference with int interval=500;

Ik heb het advies van jantje opgevolgd om mijn hele project af te breken en alleen de 2 sensoren uit te lezen met een seriele monitor, ook heb ik de 2e hall sensor analog uitgemeten, waarvan ik in mijn eerste post al de resultaten heb gegeven.

Ik heb ook door dat de interrupts niet werken omdat er constant een waardewissel is bij geen meting. Maar ik zou niet weten welke meetmethode ik dan wel toe moet passen. Want via eerdere uitleggen heb ik te horen gekregen dat als ik het niet via de interrupt methode doe, dat dan de kans bestaat dat ik een meting mis omdat de arduino bezig is met de loop.

Ik heb inmiddels al zo veel geprobeerd dat ik het niet meer weet, vandaar ook hier mijn vraag of iemand anders een idee heeft. In ieder geval een richting waar ik in kan zoeken. Dit probleem houd mij nu al een maand bezig.

In de andere thread heb ik gevraagd of ik hem misschien verkeerd heb aangesloten, ik weet het niet.

Why do you write: #define INTERVAL 500UL what is the difference with int interval=500;

DIe heb ik gemist, ik lees (te) veel threads.

OK, we gaan je een stap verder helpen.

Een #define alloceert geen geheugen waar een int dat wel doet.
500UL betekent dat het type een Unsigned long met bereik van 0..2^32; een int heeft bereik van - (2^16) .. 2^16 (+- 1)

Het voordeel van een unsigned long is dat deze veel vaker opgehoogd kan worden voordat er een overflow situatie optreedt.

Voldoende uitleg over dit verschil?


Alle verbetercodes die in detail anders waren dan mijn huidige broncode heb ik toegepast maar allemaal gaven ze geen ander resultaat.

In welke thread heb je de output gepost, zodat ik die output kan verifieren? NB dit geeft voor de lezer op het forum inzicht in het gedrag van de sketch.


In mijn post in de andere thread heb ik niet geen complete code gezet, ik heb dat uit het vuistje ingetypt omdat ik geen arduino bij de hand heb.
Ik zal het hier nog eens overdoen opdat het beter werkt.

Je merkte ergens op dat de interrupt variablen niet op nul gezet werden. Dat klopt omdat dit mogelijk een concurrency race conditie veroorzaakt,
Het was mijn doel om met deltas te werken, Ik zal dat in de onderstaande code proberen correct te doen.

Ik heb de code nog steeds niet getest maar deze zou bij benadering de RPM moeten geven, maar afhankelijk van de actuele toerental werkt deze oplossingsmethode meer of minder goed. Interrupt gebaseerde RPM meters worden onnauwkeuriger bij lage toerentallen. Als er te weinig interrupts komen tussen twee display events is geen berekening te maken omdat de RPM dan 0 aangeeft.

Niet getest geen Arduino bij de hand. (er kunnen typos inzitten)

//
//    FILE: RPM DEMO.pde
//  AUTHOR: Rob Tillaart
//    DATE: 2012-NOV-04
//
// PUPROSE: demonstrate the use of interrupts to build an RPM measure tool
//

// initialize vars while declaring
volatile unsigned long rpmHV = 0;
volatile unsigned long flowHV = 0;

unsigned long lastRPM = 0; 
unsigned long lastFLOW = 0;

unsigned long lastTime = 0; 

#define INTERVAL 500UL  // unsigned long as all timing math is done in UL.

void setup()
{
  attachInterrupt(1, rpm_fun, RISING);
  attachInterrupt(0, flow_fun, RISING);

  Serial.begin(9600);
  Serial.println("start...");
}

void loop()
{
  unsigned long now = millis();  // to prevent that the next read of millis jumps a few millisecs
  if (now - lastTime >= INTERVAL)   // every 500 milliseconds
  {
    lastTime = now;  // remember last time we displayed something

    // how many pulses since last display action
    unsigned long deltaRPM = rpmHV - lastRPM;
    unsigned long deltaFLOW = flowHV - lastFLOW;

    // display the current values
    Serial.print("time: "); 
    Serial.println(now);
    Serial.print("rpmcount: "); 
    Serial.println((deltaRPM * 60000UL) /INTERVAL);  
    Serial.print("flowcount: ");
    Serial.println(deltaFLOW );   // needs probably some math to 

    // adjust the last values 
    lastRPM += deltaRPM;
    lastFLOW += deltaFLOW;
  }
}

void rpm_fun()
{
  rpmHV++;
}

void flow_fun()
{
  flowHV++;
}

De sensoren moeten verbonden zijn met pin 2 en pin 3 (assuming you have UNO) en deze lijnen moeten voorzien zijn van een pullup danwel een pulldown weerstand om het signaal goed tussen 0 en +5V te laten schakelen.

Kun je de output van deze sketch posten?

Als er vragen zijn over de werking van de sketch hoor ik ze wel. NB de NL sectie hou ik redelijk in de gaten.

uit de andere thread

My rpm count raises randomly without any magnet in the neighbourhoud. I'm thinking that the problem have to do with the different types of hall sensor latching/ linear. But I don't know how to solve this.

Heb je links naar de specificaties/datasheets van deze 2 sensors? Onder welke magnetische veldsterkte werken ze?

uit de andere thread

maybe a very stupid question. but how do I connect the honeywell SS495A sensor.

Vragen zijn nooit stupid, niet vragen is stupid, en sommige antwoorden zijn stupid :wink:

Heb je een link naar een schematic, of evt de naam van de verwarmingsketel waarin deze gebruikt is.
Soms is enkel via de service manual te achterhalen hoe deze aangesloten dient te worden.

even snel de gevraagde documenten. Nu ga ik mijzelf even verdiepen in je gegeven code.

Datasheet flowmeter:
http://www.produktinfo.conrad.com/datenblaetter/150000-174999/150392-da-01-ml-DURCHFLUSSM_FCH_M_POM_LC_ANSCHL_6MM_de_en.pdf

Datasheet oude hall sensor
https://iprototype.nl/docs/hall-effect-technische-datasheet.pdf

Datasheet huidige hall sensor
http://www.produktinfo.conrad.com/datenblaetter/500000-524999/505292-da-01-en-POSITIONSSENSOR_SS495A1.pdf

Ik heb je code toegepast, deze werkt ook zoals de eerder gegeven code.

Ik heb alleen de flowmeter bekrachtigd (door er doorheen te blazen) Hierbij kreeg ik de volgende output.

start...
time: 500
rpmcount: 120
flowcount: 0
....
....
time: 7000
rpmcount: 0
flowcount: 0
time: 7500
rpmcount: 1080
flowcount: 8
time: 8000
rpmcount: 13080
flowcount: 110
time: 8500
rpmcount: 17880
flowcount: 149
time: 9000
rpmcount: 17400
flowcount: 145
time: 9500
rpmcount: 16800
flowcount: 140
time: 10000
rpmcount: 16320
flowcount: 136
time: 10500
rpmcount: 14760
flowcount: 123
time: 11000
rpmcount: 12000
flowcount: 100
time: 11500
rpmcount: 9960
flowcount: 83
time: 12000
rpmcount: 8280
flowcount: 69
time: 12500
rpmcount: 6840
flowcount: 57
time: 13000
rpmcount: 4920
flowcount: 41
time: 13500
rpmcount: 4320
flowcount: 35
time: 14000
rpmcount: 3600
flowcount: 31
time: 14500
rpmcount: 3240
flowcount: 26
time: 15000
rpmcount: 2640
flowcount: 22
time: 15500
rpmcount: 2160
flowcount: 18
time: 16000
rpmcount: 1680
flowcount: 14
time: 16500
rpmcount: 1200
flowcount: 11
time: 17000
rpmcount: 840
flowcount: 7
time: 17500
rpmcount: 360
flowcount: 3
time: 18000
rpmcount: 0
flowcount: 0
time: 18500
rpmcount: 0
flowcount: 0
.....
"hall sensor bekrachtigd met een npool"
....
time: 216500
rpmcount: 0
flowcount: 0
time: 217000
rpmcount: 360
flowcount: 0
time: 217500
rpmcount: 480
flowcount: 0
time: 218000
rpmcount: 240
flowcount: 0
....

Dat klopt omdat dit mogelijk een concurrency race conditie veroorzaakt,
Het was mijn doel om met deltas te werken, Ik zal dat in de onderstaande code proberen correct te doen.

Wat is een concurrency race conditie?
Als ik de deltas in de code zie, dan kan ik die vergelijken met een soort van "blink without delay" code. Dus die verschillende variabelen kan ik mijn code beheersbaarder maken door jouw delta manier toe te passen.

Beide sensoren zijn voorzien van een pull up (5V-output) weerstand van 10k

de honeywell heeft een gevoeligheid van 3-3.25mV/ Gaus??
de oude heeft een gevoeligheid van 0,5 mT?

De deltaRPM i shet aantal pulsen in het laatste interval.

(1) unsigned long deltaRPM = rpmHV - lastRPM; // deltaRPM is de huidige waarde van de teller - de vorige waarde

Dit aantal pulsen wordt dus in INTERVAL milliseconden gemaakt. Dit moet omgerekend worden naar omwentelingen per minuut. om dit te doen wordt het aantal vermenigvuldigd met 60000 (het aantal milliseconden in een minuut en gedeeld door de lengte van het INTERVAL. Als je de waarde van INTERVAL veranderd dan blijft deze formule kloppen omdat het gemeten interval ook dito korter wordt. Door het werken met delta kan de interrupt gewoon doortellen en zul je geen puls missen.

(2) Serial.println(deltaRPM * 60000UL/INTERVAL);

hoog de waarde van de vorige waarde op met de delta om de "huidige" RPM teller waarde te krijgen.
(3) lastRPM += deltaRPM;

Let op! Je mag hier niet zomaar zeggen lastRPM = RPM
want in de tijd tussen het executeren van regel (1) en regel (3) kunnen er alweer nieuwe pulsen zijn binnengekomen. Dit is een concurrency race conditie is. Doordat de interrupt in de achtergrond afgehandeld wordt heeft deze een andere waarde gekregen. NOg een voorbeeld maar dan met op nul zetten:

(assume RPM = 100)
(1) count = RPM;
(2) berekeningen met count.
(3) RPM = 0;
Nu kan tussen regel (1) en (3) de waarde van RPM opgehoogt zijn in de interrupt en dan zet je hem op 0 waardoor je pulsen mist.

Het kan nog kritischer , stel je hebt de formule
X = RPM + RPM;
dan kan de waarde van RPM veranderen net tijdens het uitrekenen van de formule met als gevolg dat X geen even getal is.

De output ziet ervreemd uit, de waarden komen perfect overeen, maar zouden 2 verschillende interrupts moeten zijn. NU lopen ze synchroon terwijl het 2 sensoren zijn. Heb je ergens een kortsluiting of heb je bewust beide ingangen 2,3 gekoppeld?
bv
rpmcount: 16800
flowcount: 140

140 * 60000 / 500 = 16800

sofar,

Dank je voor je heldere uitleg.

Ja ze lopen inderdaad gelijk op, maar alleen met de nieuwe sensor, bij de oude is dit niet. Ik heb bij conrad de gevoeligste gekocht. Ik heb misschien het idee, dat als ik de flowsensor bekrachtig dat er dan elke keer een minimale daling is in de voeding en dat de hall sensor hier op reageert.

De hall sensor reageert immers alleen op de flowsensor en niet andersom (zie laatste metingen)

Verder kan ik nergens een kortsluiting vinden.

Klinkt aannemelijk,

De pull up zit zo?

+5V ----[ 10K ]-----Arduinopin3 ------+hall+---- GND (0V)