Sari la conținut
ELFORUM - Forumul electronistilor

Indicator nivel apa


Alex vw

Postări Recomandate

Acum 1 oră, Liviu.Mihaiu a spus:

Un numar.

Nu un numar, ci 1. Uite. :)

Daca era un nomar oarecare, putea fi unul cu LSB = 0 si atunci expresia ta frumoasa, de la care a plecat totul, n-ar mai fi functionat.

Eu mai multe argumente nu mai am, asa ca ma opresc aici, cu speranta ca Mircea a inteles (cam) de ce functioneaza si ca sunt sanse sa functioneze si in basic. Si ca n-are nimic deosebit Arduino, e pur si simplu o caracteristica a C/C++.

 

LE M-am mai gandit si sunt sanse ca ce-mi imeginez eu sa fie gresit. Eu imi imaginez ca daca zic PORTA.1 = 2 (adica 0b0000 0010), PORTA.1 ramane 0, ca LSB = 0. Daca de fapt functionarea e valoare == 0 => PORTA.1 = LOW, valoare != 0 => PORTA.1 = HIGH, atunci tizul are dreptate.

 

LLE Pentru ca ma mai lasa sa modific - am testat in xc8 cu codul LATAbits.LATA0 = 2 si:

- genereaza warning la compilare
../main.c:70: warning: (762) constant truncated when assigned to bitfield

- pus breakpoint dupa LATA0 = 2, am pornit o simulare si uitat la LATA0. E 0.

 

Si cu asta gata cu topicul asta, ca l-am facut suficient praf.

 

Editat de Liviu M
Link spre comentariu
  • Răspunsuri 67
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

Top autori în acest subiect

Imagini postate

O idee care sa foloseasca mai putini pini, ar fi sa folosesti trigPin comun pentru toti cei 3 senzori si sa citesti cu o functie care emuleaza functia pulseIn, dar pentru toate cele 3 intrari:

[code]
/*
 * examplu cu 3 HC-SR04
 */
//--------------------------------------
const int trigPin = 8;
const int echoPin1 = 9, echoPin2 = 10, echoPin3 = 11;
float duration1, duration2,duration3,distance1,distance2,distance3;
//--------------------------------------
void setup() {
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin1, INPUT_PULLUP);
  pinMode(echoPin2, INPUT_PULLUP);
  pinMode(echoPin3, INPUT_PULLUP);
  Serial.begin(9600);
}
//--------------------------------------
void loop() {
  start_echo();
  pulse_3in();
  distance1 = (duration1*.0343)/2;
  distance2 = (duration2*.0343)/2;
  distance3 = (duration3*.0343)/2;
  Serial.print(distance1);
  Serial.print("   ");
  Serial.print(distance2);
  Serial.print("   ");
  Serial.println(distance3);
  
  delay(250);
}
//--------------------------------------
void start_echo(){
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
}
//--------------------------------------
void pulse_3in(){
  byte start1 = 0, end1 = 0;
  byte start2 = 0, end2 = 0;
  byte start3 = 0, end3 = 0;
  unsigned long s1, e1, s2, e2, e3, s3, w;
  w = millis();   //timeout
  while(millis()-w<500){
    if(digitalRead(echoPin1) && !start1) {
      start1=1;
      s1=micros();
    }
    if(!digitalRead(echoPin1) && start1==1) {
      start1=2;
      e1=micros();
    }
    //-------
    if(digitalRead(echoPin2) && !start2) {
      start2=1;
      s2=micros();
    }
    if(!digitalRead(echoPin2) && start2==1) {
      start2=2;
      e2=micros();
    }
    //-------
    if(digitalRead(echoPin3) && !start3) {
      start3=1;
      s3=micros();
    }
    if(!digitalRead(echoPin3) && start3==1) {
      start3=2;
      e3=micros();
    }
    if(start1+start2+start3==6) break;
  }
  duration1 = e1-s1;
  duration2 = e2-s2;
  duration3 = e3-s3;
}
[/code]

Ce faci apoi cu distantele respective (adancimea apei din fiecare bazin) e o alta poveste...

Editat de Marin1960
Link spre comentariu

O alta idee fara atatea if-uri:

/*
 * examplu cu 3 HC-SR04
 */
//--------------------------------------
const int trigPin = 8;
//const int echoPin1 = 9, echoPin2 = 10, echoPin3 = 11;
const int echoPin[3] = {9,10,11};
const float cst_vs = 0.01715;
unsigned long duration[3];
float distance[3];
//--------------------------------------
void setup() {
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin[0], INPUT_PULLUP);
  pinMode(echoPin[1], INPUT_PULLUP);
  pinMode(echoPin[2], INPUT_PULLUP);
  Serial.begin(9600);
}
//--------------------------------------
void loop() {
  pulse_3in();
}
//--------------------------------------
void pulse_3in(){
  for(byte i=0;i<3;i++){
    start_echo();
    duration[i] = pulseIn(echoPin[i],HIGH);
    distance[i] = duration[i]*cst_vs;
    Serial.print(distance[i]);
    Serial.print("   ");
    delay(100);
  }
  Serial.println();
}
//--------------------------------------
void start_echo(){
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
}
//--------------------------------------

Ambele variante au fost testate.

Link spre comentariu
2 hours ago, Marin1960 said:

O alta idee fara atatea if-uri:

Interesant exemplul al doilea.
Problema este ca aceasta modalitate mai simpla si mai frumoasa este blocking.
Pe timpul pulse_3in (3+ secunde) programul este blocat in functia asta.



 

Editat de Vizitator
Link spre comentariu

Varianta cu blocking minim pentru fiecare masuratoare (delay-ul din loop si durata functiei pulseIn(), aproximativ 3ms pentru 1 metru):

...
byte i = 0;
...
void loop() {
  start_echo();
  pulse_in(i);
  i++;
  if(i>2) i=0;
  delay(100);
}
//--------------------------------------
void pulse_in(byte i){
  duration[i] = pulseIn(echoPin[i],HIGH);
  distance[i] = duration[i]*cst_vs;
}

Problema mare eu o vad la partea de if-uri care actioneaza la atingerea unui anume nivel (de la 25% la 100%).

Un bazin cu apa se umple destul de incet, ca sa nu mai spun ca la suprafata apei se vor face valuri, indiferent de metoda de umplere (pe sus, apar valuri mari, pe jos, valuri mai mici). Pe de alta parte, un senzor HC-04 nu este foarte stabil, in concluzie ar trebui introdus un histerezis la fiecare nivel, pentru o actionare ferma si stabila. Ceva ca mai jos:

//a0 este un nivel prestabilit (a0=80)
//a = a0
void nivel(){
  if(distance >= a){
    a = a0 - histerezis;
    //actiune, Led on
  }
  else{
    a = a0 + histerezis;
    //actiune, Led off
  }
}

 

Editat de Marin1960
Link spre comentariu
1 oră în urmă, Marin1960 a spus:

Varianta cu blocking minim pentru fiecare masuratoare (delay-ul din loop si durata functiei pulseIn(), aproximativ 3ms pentru 1 metru):

...
byte i = 0;
...
void loop() {
  start_echo();
  pulse_in(i);
  i++;
  if(i>2) i=0;
  delay(100);
}
//--------------------------------------
void pulse_in(byte i){
  duration[i] = pulseIn(echoPin[i],HIGH);
  distance[i] = duration[i]*cst_vs;
}

Problema mare eu o vad la partea de if-uri care actioneaza la atingerea unui anume nivel (de la 25% la 100%).

Un bazin cu apa se umple destul de incet, ca sa nu mai spun ca la suprafata apei se vor face valuri, indiferent de metoda de umplere (pe sus, apar valuri mari, pe jos, valuri mai mici). Pe de alta parte, un senzor HC-04 nu este foarte stabil, in concluzie ar trebui introdus un histerezis la fiecare nivel, pentru o actionare ferma si stabila. Ceva ca mai jos:

//a0 este un nivel prestabilit (a0=80)
//a = a0
void nivel(){
  if(distance >= a){
    a = a0 - histerezis;
    //actiune, Led on
  }
  else{
    a = a0 + histerezis;
    //actiune, Led off
  }
}

 

Am mentionat ca partea cu leduri nu ma intereseaza ... Nu voi folosi asa ceva .

M`am gandit la partea cu valurile dar verificarea masuratorilor sa zic asa va fi facuta cand apa *sta*.

Link spre comentariu
  • 2 săptămâni mai târziu...

daca proiectul acesta e doar de prezentare merge.

dar daca se vrea a fi un proiect real, nu va merge. cineva ti-a spus mai sus ca vei avea umiditate, si indiferent cat vei lupta apa isi va spune cuvantul. tocmai de-asta, tipul acesta de proiect isi are inceputul in clarificarea senzorului folosit fata in fata cu conditiile vitrege. Vad ca se discuta despre senzor ultrasonic. Nici nu se pune in discutie un senzor sonic in mediul acela...

Link spre comentariu
  • 3 luni mai târziu...

Salut. Am nevoie ca la un proiect sa masor nivelul de apa dintr-un vas folosind un senzor cu ultrasunete si un arduino nano. Aveam prin garaj un senzor de parcare Valeo de la o masina vw cu codul 3C0919275S.Pentru a nu cheltui  bani inutil doar pentru o prezentare am zis sa incerc sa il folosesc pe acesta.  M-am gandit ca procedeul de functionare este acelasi la toti senzorii cu ultrasunete. Am cautat schita electrica pentru senzor si am gasit ca  pinul 1  este + , pinul 2 este semnal ,iar pinul 3 este masa.  Am folosit programul de aici https://www.arduino.cc/en/Tutorial/BuiltInExamples/Ping  , semnalul legat la pinul 7 digital (comun pentru trig si echo). Dar la iesire in permanenta  este  afisat 0 cm iar senzorul nu scoate nici un zgomot repetitiv specific. Aveti idee ce nu este ok? Multumesc!

Link spre comentariu

Dacă recipientul e cu pereţi din plastic, poți masura nivelul şi capacitiv, cu niște bucăti de folie de aluminiu lipite din loc în loc pe exteriorul recipientului...fiindcă pe măsură ce nivelul apei variază, se modifică şi capacitatea condensatorului format de folii, peretele recipientului şi apă.Dar asta e o variantă mai sofisticată, deşi de departe mult mai precisă.

Link spre comentariu

Creează un cont sau autentifică-te pentru a adăuga comentariu

Trebuie să fi un membru pentru a putea lăsa un comentariu.

Creează un cont

Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!

Înregistrează un nou cont

Autentificare

Ai deja un cont? Autentifică-te aici.

Autentifică-te acum



×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări