Skocz do zawartości

Pierwszy projekt - napełniacz butelek


Pomocna odpowiedź

Witam wszystkich forumowiczów.

Jestem świeżo po kursach podstaw elektroniki techniki cyfrowej i podstaw Arduino.

Kursy pokończone więc trzeba coś zacząć majsterkować ! 🙂

Małe rozeznanie już zrobiłem w temacie napędów. Podziękowania dla @farmaceuta który naprawdę pomógł. Tu link dla Ciekawych: https://forbot.pl/forum/topic/24956-serwo-pierwsze-kroki/

Zacząłem pisać kod , po pierwsze aktualny kod programu poniżej ( jeszcze nie pełny) w wolnych chwilach cały czas go rozbudowuje. Musze dodać jeszcze serwa , przyciski drugą wage i wiele innych. Część planuje nawet dołożyć jak samo urządzenie będzie działać. Wszystko po kolei 🙂

W kodzie starałem sie dać możliwie dużo opisów żeby było łatwiej zrozumieć kod i mi po dłuższej przerwie i wam gdy trzeba będzie szukać błędów.

#include <OneWire.h> // biblioteka do czujnika tempaeratury cyfrowego
#include <DallasTemperature.h> // biblioteka do czujnika tempaeratury cyfrowego
#include <LiquidCrystal_I2C.h> // biblioteka do wyswietlacza LCD
#include "HX711.h" // biblioteka do WAGI
#define DATA_PIN 2 // definicja pinu 2 jako DANE
#define CLOCK_PIN 3 // definicja pinu 3 jako CLK

HX711 scale; // Tworzymy obiekt scale typu HX711 dla wagi
LiquidCrystal_I2C lcd1(0x27, 16, 2); // Adres I2C ekranu (0x27), ilość kolumn (16) i wierszy (2)
LiquidCrystal_I2C lcd2(0x26, 16, 2); // Adres I2C ekranu (0x26), ilość kolumn (16) i wierszy (2)
OneWire oneWire(A3); //Podłączenie do A3 (Pin A3 do srodkowej nozki czujnika temperatury)
DallasTemperature sensors(&oneWire); //Przekazanie informacji do biblioteki
DeviceAddress termometrZewnetrzny = { 0x28, 0x77, 0x21, 0x12, 0x0, 0x0, 0x0, 0x9 }; // adres czujnika
DeviceAddress termometrZewnetrzny2 = { 0x28, 0x42, 0xA0, 0x10, 0x0, 0x0, 0x0, 0xE }; // adres czujnika 2

// deklaracje dla wentylatorów
const int wentylator = 7; // Pin sterujący MOSFET-em nr 1 i zarazem wentylatorem nr 1
const int wentylator2 = 8; // Pin sterujący MOSFET-em nr 2 i zarazem wentylatorem nr 2
const int temp_wlacz = 25; // Temperatura włączenia wentylatora nr 1
const int temp_wylacz = 22; // Temperatura wyłączenia wentylatora nr 1 (histereza by wentylator nie włączał i wyłączał sie bez przerwy)
const int temp_wlacz2 = 25; // Temperatura włączenia wentylatora 2
const int temp_wylacz2 = 222; // Temperatura wyłączenia wentylatora 2 (histereza by wentylator nie włączał i wyłączał sie bez przerwy)
// deklaracje dla WAGI
const int iloscOdczytow = 10; // Ilość odczytów do uśrednienia w wadze
const float wspolczynnikSkali  = -0.00000862; // <--- Wklej tutaj *obliczoną* wartość! ( roznica odczytu waga z obciazeniem - waga pusta) ( waga obciazenia podzielna przez wynik)
long wartoscTara = 85058; // <--- Wklej tutaj *obliczoną* wartość!( odczyt wagi pustej surowe dane)
//WAGA opóźnienia w millis
unsigned long ostatniOdczytCzasu = 0; // Zmienna do przechowywania czasu ostatniego odczytu
const long interwal = 100; // Interwał między odczytami (100ms)
const int przyciskTarowania = 4; // Pin 4 jako przycisk do tarowania wagi
//Zmienne millis w pętli loop
unsigned long poprzedniCzasPetliLoop = 0;
const long interwalPetliLoop = 250; // Interwał pętli głównej (250ms)


void setup(void) {
  Serial.begin(9600); // start połączenia z komputerem
  pinMode(przyciskTarowania, INPUT_PULLUP); // Ustawiamy pin jako wejście z wbudowanym rezystorem pull-up
  sensors.begin(); //Inicjalizacja czujnikow
  Wire.begin(); // Inicjalizacja magistrali I2C ( CZY TO POTRZEBNE??)
  scale.begin(DATA_PIN, CLOCK_PIN); //Inicjalizujemy HX711
  pinMode(wentylator, OUTPUT); // Wentylator (pin 7) jako wyjscie
  pinMode(wentylator2, OUTPUT); // Wentylator2 (pin 8) jako wyjscie
  digitalWrite(wentylator, LOW); // Początkowo wentylator wyłączony
  digitalWrite(wentylator2, LOW); // Początkowo wentylator wyłączony
  lcd1.init(); // Inicjalizacja ekranu 1
  lcd1.backlight(); // Włączenie podświetlenia ekranu 1
  lcd2.init(); // Inicjalizacja ekranu 2
  lcd2.backlight(); // Włączenie podświetlenia ekranu 2
}

void loop(void) {
// Debouncing przycisku
  static unsigned long poprzedniCzasPrzycisku = 0; //zapisanie czasu poprzedniego uzycia przycisku
  const unsigned long interwalDebouncingu = 50; // czas miedzy kolejnymi nacisnieciami
  unsigned long aktualnyCzas = millis(); 

  if (millis() - poprzedniCzasPrzycisku > interwalDebouncingu) { // sprawdzenie odstepu czasu przy nacisnieciu przycisku
    if (digitalRead(przyciskTarowania) == LOW) { //jezeli guzik wcisniety to:
      tarujWage(); //Wywołujemy funkcję tarującą wagę
      poprzedniCzasPrzycisku = millis(); // zmieniamy milis dla nastepnej petli
    }
  }
 
 
    if (aktualnyCzas - poprzedniCzasPetliLoop >= interwalPetliLoop) {  // Sprawdzamy, czy minął interwał dla pętli głównej
    poprzedniCzasPetliLoop = aktualnyCzas; // Aktualizujemy aktualny czas dla nastepnej pętli
   
  sensors.requestTemperatures(); //Pobranie temperatury czujnika
  Serial.print("Aktualna temperatura: "); // Piszemy do portu szeregowego "Aktualna temperatura: "
  Serial.println(sensors.getTempC(termometrZewnetrzny)); // Wyświetlenie temperatury w porcie szeregowym pobranej z czujnika
  Serial.print("Aktualna temperatura2: "); // Piszemy do portu szeregowego "Aktualna temperatura: "
  Serial.println(sensors.getTempC(termometrZewnetrzny2)); // Wyświetlenie temperatury w porcie szeregowym pobranej z czujnika
 
  termometr(); // Wywołanie funkcji  od pomiarów temperatury bez argumentu
  waga1(); // Wywołanie funkcji od wagi nr 1 bez argumentu
}
}

// FUNKCJA OBSLUGUJACA WAGE NR 1
void waga1() {
   
    float zmiennaWaga; // Deklaracja zmiennej zmiennaWaga
     
    if (scale.is_ready()) { // Sprawdzamy, czy HX711 jest gotowy do odczytu
    unsigned long aktualnyOdczytCzasu = millis(); // Pobieramy aktualny czas
     if (aktualnyOdczytCzasu - ostatniOdczytCzasu >= interwal) { // jeżeli minął interwał lub wiecej to:
      ostatniOdczytCzasu = aktualnyOdczytCzasu; // Aktualizujemy czas ostatniego odczytu dla nastepnej pętli
    long sum = 0; // Suma odczytów.
    for (int i = 0; i < iloscOdczytow; i++) { // odczytujemy odczyty az do wartości iloscOdczytow czyli 10.
      sum += scale.read(); // dodaj do sum odczyt z HX711 i zapisz w SUM
    }
    long srednia = sum / iloscOdczytow; //Obliczamy średnią.
    zmiennaWaga = (srednia - wartoscTara) * wspolczynnikSkali; //równanie kalibracji ( do uzupełnienia na poczatku kodu)
   
    // Narazie mam jedna wage wiec waga jest wyswietlana 2 raz ( naszykowane pod podpiecie drugiej wagi)
  lcd2.setCursor(0, 0); // Ustawienie kursora na początku pierwszego wiersza
  lcd2.print("WAGA1 "); //wyswietlenie tekstu
  lcd2.print(zmiennaWaga); // Wyświetlenie aktualnej wagi z tensometru
  lcd2.setCursor(0, 1); // Ustawienie kursora na początku pierwszego wiersza
  lcd2.print("WAGA2 "); //wyswietlenie tekstu
  lcd2.print(zmiennaWaga); // Wyświetlenie aktualnej wagi z tensometru

//Wyświetlamy wagę w porcie szeregowym
    Serial.print("Waga: ");
    Serial.print(zmiennaWaga);
    Serial.println(" kg");
  } else {
    Serial.println("HX711 kalibruje.."); //Komunikat, gdy HX711 nie jest gotowy.
  }
}}

// FUNKCJA TAROWANIA WAGI
void tarujWage() {
  wartoscTara = scale.read(); // Odczytujemy aktualny odczyt z wagi i zapisujemy jako waga tara
  Serial.print("Waga została wytarowana. Nowa waga tara: "); // Wyświetlenie tekstu
  Serial.println(wartoscTara);
}

// FUNKCJA TERMOMETR nr 1 i nr 2
void termometr() { // Funkcja obsługująca włączanie i wyłączenie wentylatora po zczytaniu temperatury
  float temp = sensors.getTempC(termometrZewnetrzny); // Odczyt temperatury wewnątrz funkcji
   float temp2 = sensors.getTempC(termometrZewnetrzny2); // Odczyt temperatury wewnątrz funkcji

  lcd1.setCursor(0, 0); // Ustawienie kursora na początku pierwszego wiersza
  lcd1.print("Temp1 ");// Wyświetlenie tekstu
  lcd1.print(sensors.getTempC(termometrZewnetrzny)); // Wyświetlenie temperatury z termometrZewnetrzny
  lcd1.setCursor(0, 1); // Ustawienie kursora na początku pierwszego wiersza
  lcd1.print("Temp2 ");// Wyświetlenie tekstu
  lcd1.print(sensors.getTempC(termometrZewnetrzny2)); // Wyświetlenie temperatury z termometrZewnetrzny2

  if (temp >= temp_wlacz) { // jeżeli temperatura jest wieksza od ustawionej to:
    digitalWrite(wentylator, HIGH); //Włącz wentylator
  } else if (temp <= temp_wylacz) { // jeżeli temperatura jest mniejsza od ustawionej to: ( ustawić Histereze)
    digitalWrite(wentylator, LOW); //Wyłącz wentylator
  }
  if (temp2 >= temp_wlacz2) { // jeżeli temperatura jest wieksza od ustawionej to:
    digitalWrite(wentylator2, HIGH); //Włącz wentylator2
  } else if (temp2 <= temp_wylacz2) { // jeżeli temperatura jest mniejsza od ustawionej to: ( ustawić Histereze)
    digitalWrite(wentylator2, LOW); //Wyłącz wentylator2
  }}

Pierwsze o co bym prosił to jak ktoś jest też w stanie spojrzeć kod od wagi . Robiłem to totalnie pierwszy raz wiec możliwe że coś poplątałem. Ogolnie działa ale nie wiem czy wszystko jest dobrze. Głównie chodzi mi o skalowanie tarowanie itd.

I ogólna ocena kodu + co można poprawić 🙂

 

Z góry dzięki !

Edytowano przez PanMajster
Link do komentarza
Share on other sites

2 godziny temu, PanMajster napisał:

Robiłem to totalnie pierwszy raz wiec możliwe że coś poplątałem. Ogolnie działa ale nie wiem czy wszystko jest dobrze. Głównie chodzi mi o skalowanie tarowanie itd.

A parę słów opisu jak to coś ma działać?

2 godziny temu, PanMajster napisał:

Z góry dzięki !

 

Link do komentarza
Share on other sites

@Sylba Ogólny zamysł będzie taki ze po naciśnięciu przycisku powiedzmy "Start" Serwo nr 1 będzie otwierać pojemnik po otwarciu pojemnika serwo nr2 bedzie odkrecac dopływ cieczy która zacznie przepływać  do pojemnika który będzie umieszczony na wadze. Po osiągnieciu danej wagi serwo nr 1 zamyka pojemnik a serwo nr 2 zamyka dopływ cieczy. Do tego kontrola temperatury mikrokontrolera i zasilaczy  by w razie czego schłodzić układ.

Załączanie i wyłączanie serw jeszcze nie ma w kodzie bo nie mam samych serw. Na razie dodałem struktury wag , i wentylatorów i pomiaru temperatury. Nad reszta bede pracować i na bieżąco aktualizować. Zastanawia mnie jednak kod od wagi który chyba jest dobry bo działa ale czy nie ma tam nic zbędnego to pewien nie jestem.

Link do komentarza
Share on other sites

25 minut temu, PanMajster napisał:

Ogólny zamysł będzie taki ze po naciśnięciu przycisku powiedzmy "Start" Serwo nr 1 będzie otwierać pojemnik po otwarciu pojemnika serwo nr2 bedzie odkrecac dopływ cieczy która zacznie przepływać  do pojemnika który będzie umieszczony na wadze. Po osiągnieciu danej wagi serwo nr 1 zamyka pojemnik a serwo nr 2 zamyka dopływ cieczy. Do tego kontrola temperatury mikrokontrolera i zasilaczy  by w razie czego schłodzić układ.

To zaszalałeś z opisem. Tyle tylko, że niewiele z tego opisu wynika. Czy mógłbyś uchylić rąbka tajemnicy i napisać coś więcej o samym urządzeniu? Może jakiś poglądowy (schematyczny) obrazek?

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

@Sylba narazie mam to tylko w głowie:D

obrazka nie mam bo nie znalazłem w internecie nic podobnego. Mogę spróbować coś takiego zrobić tyle że wszystkie części fizyczne będę dopiero sam tworzyć. Tzn podłączanie pojemników do instalacji z cieczą. Nie da się tego kupić ani narysować jakoś konkretnie bo to jeszcze nie istnieje. Serwa będą sterować zaworami które będą otwierać i zamykać dopływ. 

Może latwiej jak to wytłumaczę na bazie wody i zbiorników na wodę. Łatwiej będzie zobrazować. 

Potrzebuje maszyny która automatycznie będzie obsługiwać dwa zawory kulowe.  Jeden zawór to dopływ wody do pojemnika. Drugi zawór to otwieranie i zamykanie samego pojemnika. (Tu są potrzebne dwa serwa). Po napełnieniu pojemnika (na kg) czyli osiągnięciu pożądanej wagi pojemnika wraz z wodą. Zawór z dopływem będzie zamykany i pojemnik na wodę będzie zamykany.

I tak w kółko będę zmieniać pojemniki. Dzięki takiej maszynie będę mógł napełniać po kilka pojemników na raz nie przejmując się że gdzieś coś mi się przeleje bo Arduino będzie sam zakańczać napełnianie gdy pojemnik będzie pełny. Ja tylko będę mieć za zadanie podstawianie pustych pojemników i wciskania przycisku "start"

 

Link do komentarza
Share on other sites

Rozumiem, że chcesz napełniać różne pojemniki określoną ilością wody.
Do odmierzania ilości wody będziesz używał wagi.
Algorytm działania urządzenia ma być taki:
- pusty pojemnik jest stawiany na wadze
- następuje tarowanie wagi
- otwarcie zaworu na rurze napełniania wodą
- pomiar ilości (masę/wagę) nalewanej wody
- zakręcenie zaworu gdy ilość nalanej wody osiągnie zakładaną wielkość
- zdjęcie z wagi napełnionego pojemnika

Czy tak ma działać?

Link do komentarza
Share on other sites

@Sylba na ten moment dokładnie tak. 

Później chce dołożyć jeszcze pompę regulująca ciśnienie wody w układzie za pomocą jakiegoś czujnika ciśnienia. Ale to już w późniejszym etapie jak wszytko będzie działać 

Link do komentarza
Share on other sites

34 minuty temu, PanMajster napisał:

obrazka nie mam bo nie znalazłem w internecie nic podobnego. Mogę spróbować coś takiego zrobić tyle że wszystkie części fizyczne będę dopiero sam tworzyć.

Zakładam, że koncepcja jest twoja, to po co obrazek z internetu? Rozmawiamy o idei, a nie o detalach i konkretnych częściach.

Projektujesz wszystko na raz. Nie obawiasz się, że aby zbudować kolejne elementy będziesz potrzebował wiedzy o innych elementach, których jeszcze nie masz?
A masz jakieś założenia liczbowe np. wielkość pojemnika, ilość pojemników, które chcesz napełnić w ciągu godziny/dnia/doby? Czy pojemniki mają być ciśnieniowe czy bezciśnieniowe?

Link do komentarza
Share on other sites

38 minut temu, PanMajster napisał:

@Sylba jeden zawór to dopływ wody do pojemnika. Drugi zawór to otwieranie i zamykanie samego pojemnika. (Tu są potrzebne dwa serwa). 

W jaki sposób ma się odbywać otwieranie zamykanie pojemnika?? Po co dwa serwa do tego?

Link do komentarza
Share on other sites

(edytowany)
30 minut temu, PanMajster napisał:

@Sylba

Później chce dołożyć jeszcze pompę regulująca ciśnienie wody w układzie za pomocą jakiegoś czujnika ciśnienia. Ale to już w późniejszym etapie jak wszytko będzie działać 

Po co chcesz regulować ciśnieniem? To nie ma tak działać że się poprostu nalewa po otwarciu zaworu i tyle? Co do samych czujników to żaden problem...jest tego cała masa, zazwyczaj są to czujniki analogowe więc w sterowaniu też nie są wymagające...

Edytowano przez farmaceuta
  • Lubię! 1
Link do komentarza
Share on other sites

(edytowany)

 

 

 

33 minuty temu, Sylba napisał:

Projektujesz wszystko na raz. Nie obawiasz się, że aby zbudować kolejne elementy będziesz potrzebował wiedzy o innych elementach, których jeszcze nie masz?
A masz jakieś założenia liczbowe np. wielkość pojemnika, ilość pojemników, które chcesz napełnić w ciągu godziny/dnia/doby? Czy pojemniki mają być ciśnieniowe czy bezciśnieniowe?

Mam w głowie ogólną koncepcję. Raczej nie będzie problemu a w razie czego zmodyfikuje KOD/Instalację.
Liczbowe tak mniej wiecej mam. ok 100 pojemników po 6kg dziennie . Pojemniki będą ciśnieniowe. Tak jak pisałem w dziale z napędami "woda" to bedzie gaz w fazie ciekłej o dość dużym cisnieniu zmieniajacym sie zależnie od temperatury. Analogia z woda jest łatwiejsza do wytłumaczenia. żeby wszystkiego nie zagmatwać za bardzo

33 minuty temu, farmaceuta napisał:

W jaki sposób ma się odbywać otwieranie zamykanie pojemnika?? Po co dwa serwa do tego?

Będe zakładać na pojemniki zawory jedno kierunkowe. Pojemnik ma sie napełnic a po odcieciu cisnienia sam sie zamknie. 
1 serwo od dopływu cieczy drugie jest otwierajace zawór jednokierunkowy. Po powrocie serwa do pozycji wyjsciowej zawór sam sie zamyka.
 

30 minut temu, farmaceuta napisał:

Po co chcesz regulować ciśnieniem? To nie ma tak działać że się poprostu nalewa po otwarciu zaworu i tyle? Co do samych czujników to żaden problem...jest tego cała masa, zazwyczaj są to czujniki analogowe więc w sterowaniu też nie są wymagające...

Ciśnieniem ponieważ zeby dobrze napełnić pojemnik potrzebne bedzie cisnienie.

Czujniki tez bedą musiały być czymś wiecej niż standardem dostepnym na znanych portalach. Ciśnienie robocze miedzy 60-110 bar.

Zawory kulowe w sumie tez. Mam na 500bar z którymi pracuje na co dzień.

28 minut temu, Santiago napisał:

@farmaceuta dokładnie nie rozumiem o co tu chodzi 🙂

Mam nadzieję że troche rozjaśniłem 🙂

 

 

Edytowano przez PanMajster
Link do komentarza
Share on other sites

40 minut temu, PanMajster napisał:

Liczbowe tak mniej wiecej mam. ok 100 pojemników po 6kg dziennie . Pojemniki będą ciśnieniowe. Tak jak pisałem w dziale z napędami "woda" to bedzie gaz w fazie ciekłej o dość dużym cisnieniu zmieniajacym sie zależnie od temperatury.

 

45 minut temu, PanMajster napisał:

Czujniki tez bedą musiały być czymś wiecej niż standardem dostepnym na znanych portalach. Ciśnienie robocze miedzy 60-110 bar.

Zawory kulowe w sumie tez. Mam na 500bar z którymi pracuje na co dzień.

I do sterowania chcesz użyć Arduino? A co na to UDT?

 

  • Lubię! 1
Link do komentarza
Share on other sites

(edytowany)

@Sylba W razie kontroli UDT przede wszystkim sprawdza czy masz uprawnienia do nabijania takich butli a ja mam zajmuje się tym od 10 lat. Właśnie dlatego nie chciałem wchodzić w szczegóły a pracować na analogi wodnej. Zamiast rozwiązywać problemy i ulepszać program będziemy rozmawiać o uprawnieniach, pozwoleniach i aspektach fizycznych gazów...

 

40 postów odkąd wrzuciłem post z prośbą o sprawdzenie kodu i nikt nawet nie raczył spojrzeć 😛

Edytowano przez PanMajster
Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.