Hallo zusammen,
beschäftige mich gerade mit dem erlernen der Arduino-Programmierung.
Ich habe mir bisher immer Programmschnipsel oder fertige Sketches aus dem www besorgt und diese dann nach meinen Wünschen geändert (für mich eine Art learning by doing).
Jetzt hänge ich aber total, bei zwei Dingen.
Erstmal zu meinem Vorhaben: Ich möchte eine Dosieranlage für Flüssigwaschmittel bauen. Arduino Uno, Schlauchpumpe und Durchflusssensor vorhanden, verkabelt und funktioniert auch soweit. Die Pumpe hängt übrigens an einem 1-Kanal-Relaysmodul mit Optokoppler.
Logischerweise läuft der Sketch durch, sobald der Arduino Strom bekommt oder Reset gedrückt wird. Und genau das möchte ich erst, wenn ich eine Taste drücke (vom Shield wäre die "Select" Taste noch frei).
Zu meinem anderen Problem komme ich unten nach dem Code.
Hier mein Sketch:
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
int lcd_key = 0;
int adc_key_in = 0;
float current_volume = 0; //Current total volume passed though flow meter
float target_volume = 0.5; //Total desired volume
float adjustment_volume = 0; //Adjustment volume to take into account delays in solenoid closing. Subtracted from the current volume.
#define btnRIGHT 0
#define btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnSELECT 4
#define btnNONE 5
#define hltSIZE 0.6 //Size of the Hot Liquor Tun in litres
#define SOLENOIDPIN 13 //Solenoid relay on Pin 13
#define FLOWSENSORPIN 12 //Flow sensore on Pin 2
// count how many pulses
volatile uint16_t pulses = 0;
// track the state of the pulse pin
volatile uint8_t lastflowpinstate;
// you can try to keep time of how long it is between pulses
volatile uint32_t lastflowratetimer = 0;
// and use that to calculate a flow rate
volatile float flowrate;
// Interrupt is called once a millisecond, looks for any pulses from the sensor!
SIGNAL(TIMER0_COMPA_vect) {
uint8_t x = digitalRead(FLOWSENSORPIN);
if (x == lastflowpinstate) {
lastflowratetimer++;
return; // nothing changed!
}
if (x == HIGH) {
//low to high transition!
pulses++;
}
lastflowpinstate = x;
flowrate = 1000.0;
flowrate /= lastflowratetimer; // in hertz
lastflowratetimer = 0;
}
void useInterrupt(boolean v) {
if (v) {
// Timer0 is already used for millis() - we'll just interrupt somewhere
// in the middle and call the "Compare A" function above
OCR0A = 0xAF;
TIMSK0 |= _BV(OCIE0A);
} else {
// do not call the interrupt function COMPA anymore
TIMSK0 &= ~_BV(OCIE0A);
}
}
void setup()
{
Serial.begin(9600);
Serial.print("Flow sensor test!");
digitalWrite(SOLENOIDPIN,LOW); //ACTIVE HIGH RELAY PUT THIS FIRST TO ENSURE PIN IS IN CORRECT STATE BEFORE WE INIT IT
digitalWrite(FLOWSENSORPIN, HIGH);
pinMode(SOLENOIDPIN, OUTPUT);
pinMode(FLOWSENSORPIN, INPUT);
lcd.begin(16, 2); // start the library
printBanner(3000); // show banner for 2 seconds
lcd.clear();
printLabels();
lastflowpinstate = digitalRead(FLOWSENSORPIN);
useInterrupt(true);
}
void loop()
{
while(current_volume < (target_volume - adjustment_volume))
{
dowork();
}
digitalWrite(SOLENOIDPIN,HIGH); //Close solenoid //normal low!!
lcd.setCursor(0,0);
lcd.print("Waschm. dosieren");
lcd.setCursor(0,1);
lcd.print(" Start druecken ");
//Debug Messaging
Serial.println(" VALVE CLOSED ");
Serial.println(" TARGET HIT ");
}
void printBanner(int bannerdelay)
{
lcd.setCursor(0,0);
lcd.print(" Waschmittel ");
lcd.setCursor(0,1);
lcd.print(" wird dosiert ");
delay(bannerdelay);
}
void printLabels()
{
lcd.setCursor(0,0);
lcd.print("Ziel: ");
lcd.setCursor(0,1);
lcd.print("Aktuell: ");
}
// read the buttons
int read_LCD_buttons()
{
adc_key_in = analogRead(0);
/* OLD BUTTONS at 3.3V
if (adc_key_in > 1000) return btnNONE;
if (adc_key_in < 50) return btnRIGHT;
if (adc_key_in < 195) return btnSELECT;
if (adc_key_in < 380) return btnUP;
if (adc_key_in < 555) return btnDOWN;
if (adc_key_in < 790) return btnLEFT;
*/
if (adc_key_in > 1000) return btnNONE;
if (adc_key_in < 50) return btnRIGHT;
if (adc_key_in < 195) return btnUP;
if (adc_key_in < 380) return btnDOWN;
if (adc_key_in < 555) return btnLEFT;
if (adc_key_in < 790) return btnSELECT;
return btnNONE;
}
void dowork()
{
//Serial.print("Freq: "); Serial.println(flowrate); //Uncomment these two lines to monitor the freq/pulses
//Serial.print("Pulses: "); Serial.println(pulses, DEC);
float liters = pulses;
liters /= 7.5;
liters /= 60.0;
current_volume = liters;
//Debug Messaging
Serial.print("Cur: "); Serial.println(current_volume);
Serial.print("Tar: "); Serial.println(target_volume);
//Print the target volume value in litres
lcd.setCursor(11,0);
lcd.print(target_volume,2);
lcd.setCursor(15,0);
lcd.print("L");
//Print the current volume value in litres
lcd.setCursor(11,1);
lcd.print(current_volume,2);
lcd.setCursor(15,1);
lcd.print("L");
lcd_key = read_LCD_buttons(); // read the buttons
switch (lcd_key) // depending on which button was pushed, we perform an action
{
case btnRIGHT:
{
if (digitalRead(SOLENOIDPIN == HIGH))
{
digitalWrite(SOLENOIDPIN,LOW); //STOP FLOW
}
Serial.println("Solenoid Closed");
break;
}
case btnLEFT:
{
if (digitalRead(SOLENOIDPIN == LOW))
{
digitalWrite(SOLENOIDPIN,HIGH); //START FLOW
}
Serial.println("Solenoid Open");
break;
}
case btnUP:
{
if (target_volume >= hltSIZE) //don't go larger than the size of the vessel
{
target_volume = hltSIZE;
break;
}
else
{
target_volume += 0.01;
break;
}
break;
}
case btnDOWN:
{
if (target_volume <= 0) //don't go below zero
{
target_volume = 0;
break;
}
else
{
target_volume -= 0.01;
}
break;
}
case btnNONE:
{
break;
}
}
}
Mein anderes Problem wäre, dass der Pin 13 an dem meine Pumpe hängt, nach Reset oder Energiezuführung kurz in undefinierten Zuständen "flackert" und dann erst low bleibt. Gibts dafür Abhilfe?
Besten Dank im Voraus!
Gruß
Bonsai