• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Problem z projektem wykrywacza metalu
#1

.txt   metal pomiar - 400.txt (Rozmiar: 3.23 KB / Pobrań: 1) Więc sytuacja wygląda tak:

Zrobiłem ten projekt na arduino uno i działa: https://www.instructables.com/Simple-Ard...-Detector/
ale chciałem dodać do niego również wyświetlacz Lcd 16x2. Udało się, ale wyświetlacz nie pokazuje odczytów od zera, tylko od około 490. Próbowałem to zmienić, robiąc z pomiaru na pinie A1 zmnienną i odejmując od wyświetlanej zmiennej 490, ale wyświetlacz zaczął pokazywać dziwne wyniki, chyba minimalne wartości po przecinku. Ale tu wchodzi kolejny problem, mianowicie kiedy przyłożę do cewki metalowy przedmiot wyniki nie zerują się Sad . W wersji programu bez odejmowana od zmiennej pomiar 490 wynik wraca do pierwotnej postaci po oddaleniu metalu od cewki.
Mam 14 lat i chodzę do 1 klasy technikum, kierunek mechatronika, projekt wykrywacza robię w ramach nauki na własną rękę, bo w szkole na razie prawo Ohma przerabiamy Wink .

Czy jest ktoś kto wie co zrobić, aby wartość pomiaru zerowała się i na początku była zerowa?

Mój program jest w załączniku.
 
Odpowiedź
#2
Kod wstawiaj w znaczniku, pełna edycja postu:
Kod:
/*
* Metal detector
* We use the code of this project,
* with minor changes:
* https://www.instructables.com/id/Simple-Arduino-Metal-Detector/
*/
#include <LiquidCrystal.h>
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
 
const byte npulse = 12; // number of pulses to charge the capacitor before each measurement

const byte pin_pulse = A0; // sends pulses to charge the capacitor (can be a digital pin)
const byte pin_cap  = A1; // measures the capacitor charge
const byte pin_LED = 12; // LED that turns on when metal is detected
   int pomiar =0;
void setup() {
   Serial.begin(9600);


   
   lcd.begin(16, 2);
 

 
  pinMode(pin_pulse, OUTPUT);
  digitalWrite(pin_pulse, LOW);
  pinMode(pin_cap, INPUT);
  pinMode(pin_LED, OUTPUT);
  digitalWrite(pin_LED, LOW);
}

const int nmeas = 256; //measurements to take
long int sumsum = 0; //running sum of 64 sums
long int skip = 0; //number of skipped sums
long int diff = 0;      //difference between sum and avgsum
long int flash_period = 0; //period (in ms)
long unsigned int prev_flash = 0; //time stamp of previous flash

void loop() {
pomiar = analogRead(A1);
 
lcd.setCursor(0, 0);

  lcd.print(pomiar - 488);

  int minval = 2000;
  int maxval = 0;

  //perform measurement
  long unsigned int sum = 0;
  for (int imeas = 0; imeas < nmeas + 2; imeas++) {
    //reset the capacitor
    pinMode(pin_cap, OUTPUT);
    digitalWrite(pin_cap, LOW);
    delayMicroseconds(20);
    pinMode(pin_cap, INPUT);
    //apply pulses
    for (int ipulse = 0; ipulse < npulse; ipulse++) {
      digitalWrite(pin_pulse, HIGH); //takes 3.5 microseconds
      delayMicroseconds(3);
      digitalWrite(pin_pulse, LOW); //takes 3.5 microseconds
      delayMicroseconds(3);
    }
    //read the charge on the capacitor
    int val = analogRead(pin_cap); //takes 13x8=104 microseconds
    minval = min(val, minval);
    maxval = max(val, maxval);
    sum += val;

    //determine if LEDs should be on or off
    long unsigned int timestamp = millis();
    byte ledstat = 0;
    if (timestamp < prev_flash +12) {
      if (diff > 0)ledstat = 1;
      if (diff < 0)ledstat = 2;
    }
    if (timestamp > prev_flash + flash_period) {
      if (diff > 0)ledstat = 1;
      if (diff < 0)ledstat = 2;
      prev_flash = timestamp;
    }
    if (flash_period > 1000)ledstat = 0;

    //switch the LEDs to this setting
    if (ledstat == 0) {
      digitalWrite(pin_LED, LOW);
    }
    if (ledstat == 1) {
      digitalWrite(pin_LED, LOW);
    }
    if (ledstat == 2) {
      digitalWrite(pin_LED, HIGH);
    }

  }

  //subtract minimum and maximum value to remove spikes
  sum -= minval; sum -= maxval;

  //process
  if (sumsum == 0) sumsum = sum << 6; //set sumsum to expected value
  long int avgsum = (sumsum + 32) >> 6;
  diff = sum - avgsum;
  if (abs(diff)<avgsum >> 10) {   //adjust for small changes
    sumsum = sumsum + sum - avgsum;
    skip = 0;
  } else {
    skip++;
  }
  if (skip > 64) {  // break off in case of prolonged skipping
    sumsum = sum << 6;
    skip = 0;
  }

  // one permille change = 2 ticks/s
  if (diff == 0) flash_period = 1000000;
  else flash_period = avgsum / (2 * abs(diff));
  Serial.println(A1);
}
Co do zasady LCD zapamiętuje wysłane znaki i wyświetla je dopóki nie nadpiszesz ich innymi. Przed wysłaniem właściwych danych albo wyślij linię spacji, albo komendę czyszczenia ekranu, albo buduj linię do wysłania w buforze i dopiero z tego buforu cyklicznie wysyłaj linie na ekran.
Na LCD nie warto wysyłać niczego częściej niż co 100ms. Czas wysyłania zakłóci inne pomiary czasu. Naucz się używać millis(). Miłej nauki na kursach Arduino, nie warto ich pomijać, bo to tam pewnie wszystko o tym było - podstawy.
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości