Probleem met Hall Sensor

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)

ik heb hem zo

de honeywell heeft een gevoeligheid van 3-3.25mV/ Gaus??

Zou dit betekenen dat dit een analoge sensor is?

de oude heeft een gevoeligheid van 0,5 mT?

En dit een digitale?

10.000 Gauss = 1 Tesla ==> 0.5 mT = 5 Gauss

Wordt de Hall sensor warm als ie aangesloten is?

IK duik even indedatatsheets/

from - http://bildr.org/2011/04/ -

Melexis US1881
The Melexis US1881 (available from sparkfun at $0.95) is a Latching Hall Effect Sensor meaning that once it is triggered it latches and will not unlatch until a magnetic force of reverse polarity and strength is sensed. So If the north pole of a magnet turned it on, the south pole of a magnet is then needed to turn it off. When the US1881 is triggered the output will be equal to the source voltage (3.5 to 24V) and unlatched will output 0v/ground.

I did find that using an overly strong magnet with this sensor would sometimes not latch it or would latch it to the point that it was hard to unlatch. So keep your 1in rare earth magnets away from this one.

Als ik dit lees lijkt het me een minder geschikte sensor om een voorbijgaand magnetisch veld te detecteren omdat je een tegenovergesteld magnetisch veld nodig hebt om hem terug te zetten. De vraag is of dat je in jouw meetopstelling een 2 magneet hebt die tegenovergesteld gericht staat.

PS, Aansluiting ziet er op zich OK uit.

De 2e Hall sensor geeft volgens mij een analoge uitgangsspanning afhankelijk van het magnetisch veld. 3mV/Gauss klinkt dan betekenisvol.

DIt zou je met een VOltmeter moeten kunnen verifieren. Kun je dat doen?

from - http://sensing.honeywell.com/index.php?ci_id=3108&la_id=1&pr_id=36221&utm_source=supplyFrame&utm_medium=SEP -

SS490 Series MRL (Miniature Ratiometric Linear) sensors have a ratiometric output voltage, set by the supply voltage. It varies in proportion to the strength of the magnetic field.
A new Hall effect integrated circuit chip provides increased temperature stability and sensitivity. Laser trimmed thin film resistors on the chip provide high accuracy and temperature compensation to reduce null and gain shift over temperature. The quad Hall sensing element minimizes the effects of mechanical or thermal stress on the output. The positive temperature coefficient of the sensitivity helps compensate for the negative temperature coefficients of low cost magnets, providing a robust design over a wide temperature range.

dus een analoge uitgang.

klopt de honeywell is een analoge. Dit heb ik ook gemeten met de proefcode van arduino tutorials. Geen magneet een veranderende waarde tussen de 506-512, wanneer de noordpool langskomt gaat hij richting de 0 (hoe dichterbij hoe lager de waarde), bij een z-pool gaat hij richting de 1023 (hoe dichterbij hoe hoger de waarde). (is het nu nog steeds nuttig dit na te meten met een voltmeter?)

De oude(melexis) heeft inderdaad een z-pool nodig om te resetten, alleen de schijf die ik gekocht heb, heeft alleen maar N-polen naar buiten gericht. En die schijf was behoorlijk duur, dus had besloten de sensor te vervangen. (door de honeywell) De melexis heeft inderdaad maar 2 standen: 0 of 1023.

de hall sensor wordt naar mijn weten niet warm.

als ik verder lees bij bildr.org kan ik dan niet beter deze aanschaffen? OPTEK Technology OH090U

(is het nu nog steeds nuttig dit na te meten met een voltmeter?)

nee, het analoge gedrag is nu inmiddels wel duidelijk :slight_smile:

Geen magneet een veranderende waarde tussen de 506-512

Dit is ~2.5 Volt, en dat is voor de digitale IO lijn (de interrupt lijn) een ongedefineerde waarde, soms 0 soms 1 dus ik kan me voorstellen dat het gevoelig is voor externe signalen. Dit verklaart volgens mij het gedrag van je systeem.

Om een nette puls te krijgen voor de IRQ lijn je dit analoge signaal omzetten in een 0V - 5V signaal. Nu ben ik geen electronicus maar ik denk dat je met de analoge Hall sensor een transistor moet schakelen, zodat die een bepaalde drempelwaarde "geleid" als een schakelaar.

Kan iemand met meer E kennis details geven van een dergelijke schakeling?

@ robtillaart.

Nogmaals bedankt voor al je geboden hulp, via het engelse draadje kwam iemand met de tip om toch voor een andere sensor te gaan , dit ga ik ook doen.

Maar ik ben ook bezig om die specifieke stukken code toe te passen die jij voorgesteld hebt, alleen hier heb ik nog een paar vraagjes over:

if (now - lastTime >= INTERVAL)

is dit bestand tegen de overflow, dit omdat ik het systeem zo maak dat hij het hele jaar bekrachtigd wordt.
of is dit beter?

(long)(now-millishv) >=0)

Ook werk jij met deltaRPM, op den duur gaat ook de RPM/Flow telling in de overflow krijg ik hier last van met de delta formule?

Ik ga uit van deze code:

//
//    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++;
}

Maar ik ben ook bezig om die specifieke stukken code toe te passen die jij voorgesteld hebt, alleen hier heb ik nog een paar vraagjes over:

Code:
if (now - lastTime >= INTERVAL)
is dit bestand tegen de overflow, dit omdat ik het systeem zo maak dat hij het hele jaar bekrachtigd wordt.
of is dit beter?
Code:
(long)(now-millishv) >=0)

Dit kun je gewoon uitproberen door een test sketch te schrijven. Het eerste is bestand tegen overflow, dat weet ik, de 2e constructie heb ik nooit geprobeerd.

Ook werk jij met deltaRPM, op den duur gaat ook de RPM/Flow telling in de overflow krijg ik hier last van met de delta formule?

Omdat de deltas iedere keer opnieuw worden uitgerekend tov de vorige waarde zal er geen overflow zijn.

even modulo 10 : 9-8=1 0-8=2 1-8=3 2-8=4 etc

robtillaart:
Om een nette puls te krijgen voor de IRQ lijn je dit analoge signaal omzetten in een 0V - 5V signaal. Nu ben ik geen electronicus maar ik denk dat je met de analoge Hall sensor een transistor moet schakelen, zodat die een bepaalde drempelwaarde "geleid" als een schakelaar.

Kan iemand met meer E kennis details geven van een dergelijke schakeling?

Het klopt dat je dit beter kunt versterken, maar met 1 transistor kom je er niet ben ik bang.
Meestal word voor dit soort omzettingen een versterker chipje gebruikt dat in de volksmond een opamp heet.
De LM358 is daar een heel bekend voorbeeld van.
Die kun je zo opzetten dat die het signaal uit je analoge sensor omzet naar een digitaal signaal.
Daarvoor sluit je de sensoruitgang aan op de ene ingang en een vooringestelde waarde op de tweede ingang.
Je maakt geen gebruik van terugkoppeling (de uitgang word niet via een weerstand verbonden met een van de ingangen).
Wanneer nu je sensorwaarde boven de vooringestelde waarde uitkomt, klapt de uitgang om (bijvoorbeeld van 0 volt naar 5 volt).
Dat is precies wat je wil.
Die vooringestelde waarde is gewoon een (10 K) potmeter tussen 0 en 5 volt en de middelste pin komt dan aan de tweede ingang van de opamp.
Een LM358 heeft 2 stuks van dezelfde schakeling, en wanneer je er maar eentje gebruikt, dien je van de andere de 3 pinnetjes met elkaar te verbinden.
Wanneer het noodzakelijk is dat de schakeling andersom werkt, dan kun je de twee ingangen met elkaar verwisselen (dan klapt ie dus om van 5 naar 0 volt in het voorbeeld).
Bijkomend voordeel van zo'n opamp is dat het de uitgang van je sensor nagenoeg niet belast en daarom je meting niet zal beïnvloeden.

Dit alles kun je ook bereiken met een analoge ingang van je Arduino, maar een opamp schakeling is bijna oneindig sneller dan een analoge waarde binnenhalen en dan kijken of die boven de drempelwaarde uitkomt of niet.

Ik heb nog ff een beetje geoefend en gespeeld (dat kan hetzelfde zijn) met Fritzing, en een plaatje gemaakt van hoe je de schakeling met de opamp kunt bedraden.
De rode en zwarte draden zijn de voeding.
De blauwe draadjes zijn de doorverbinding waar ik het over had.
Het onderdeel met de vraagteken is de hall sensor, ik ga er van uit dat deze 3 aansluitingen heeft maar weet niet welke draad waar zou gaan.
De groene draad is de uitgang van de hall sensor, de gele draad die van de potmeter.
Alleen het pennetje vlak boven de M is niet aangesloten in dit schetsje.
Dat is de uitgang waarvan het nivo omklapt als aan de gestelde voorwaarde word voldaan ( hall > pot), en dient dus te worden aangesloten op je Arduino.
Het blauwe onderdeeltje is een (100 nF) condensatortje die stoorpulsen moet onderdrukken voor de opamp.
De potmeter mag een waarde van 10 K of hoger hebben (dus niet lager).