Dosieranlage mit Arduino - kurze Frage

Gast #4985436
Lesenswert?

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:
1
#include <LiquidCrystal.h>
2

3
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
4

5
int lcd_key     = 0;
6
int adc_key_in  = 0;
7
float current_volume = 0;                //Current total volume passed though flow meter
8
float target_volume = 0.5;                //Total desired volume
9
float adjustment_volume = 0;             //Adjustment volume to take into account delays in solenoid closing. Subtracted from the current volume.
10

11
#define btnRIGHT  0
12
#define btnUP     1
13
#define btnDOWN   2
14
#define btnLEFT   3
15
#define btnSELECT 4
16
#define btnNONE   5
17

18
#define hltSIZE   0.6                       //Size of the Hot Liquor Tun in litres
19

20
#define SOLENOIDPIN 13                      //Solenoid relay on Pin 13
21
#define FLOWSENSORPIN 12                    //Flow sensore on Pin 2
22

23
// count how many pulses
24
volatile uint16_t pulses = 0;
25
// track the state of the pulse pin
26
volatile uint8_t lastflowpinstate;
27
// you can try to keep time of how long it is between pulses
28
volatile uint32_t lastflowratetimer = 0;
29
// and use that to calculate a flow rate
30
volatile float flowrate;
31
// Interrupt is called once a millisecond, looks for any pulses from the sensor!
32
SIGNAL(TIMER0_COMPA_vect) {
33
  uint8_t x = digitalRead(FLOWSENSORPIN);
34
  
35
  if (x == lastflowpinstate) {
36
    lastflowratetimer++;
37
    return; // nothing changed!
38
  }
39
  
40
  if (x == HIGH) {
41
    //low to high transition!
42
    pulses++;
43
  }
44
  lastflowpinstate = x;
45
  flowrate = 1000.0;
46
  flowrate /= lastflowratetimer; // in hertz
47
  lastflowratetimer = 0;
48
}
49

50
void useInterrupt(boolean v) {
51
  if (v) {
52
    // Timer0 is already used for millis() - we'll just interrupt somewhere
53
    // in the middle and call the "Compare A" function above
54
    OCR0A = 0xAF;
55
    TIMSK0 |= _BV(OCIE0A);
56
  } else {
57
    // do not call the interrupt function COMPA anymore
58
    TIMSK0 &= ~_BV(OCIE0A);
59
  }
60
}
61

62
void setup()
63
{
64
    
65
  Serial.begin(9600);
66
  Serial.print("Flow sensor test!");
67
  
68
  digitalWrite(SOLENOIDPIN,LOW);           //ACTIVE HIGH RELAY PUT THIS FIRST TO ENSURE PIN IS IN CORRECT STATE BEFORE WE INIT IT
69
  digitalWrite(FLOWSENSORPIN, HIGH);
70

71
  pinMode(SOLENOIDPIN, OUTPUT);
72
  pinMode(FLOWSENSORPIN, INPUT);
73

74
  
75
  lcd.begin(16, 2);                        // start the library
76

77
  printBanner(3000);                       // show banner for 2 seconds
78
  
79
  lcd.clear();
80
  
81
  printLabels();
82
  
83
  lastflowpinstate = digitalRead(FLOWSENSORPIN);
84
  useInterrupt(true);
85

86
}
87
void loop()
88
{
89

90
  while(current_volume < (target_volume - adjustment_volume))
91
  { 
92
    dowork();
93
  }
94
  
95
  digitalWrite(SOLENOIDPIN,HIGH);          //Close solenoid //normal low!!
96

97
  lcd.setCursor(0,0);
98
  lcd.print("Waschm. dosieren");
99
  lcd.setCursor(0,1);
100
  lcd.print(" Start druecken ");
101
  
102
  //Debug Messaging
103
  Serial.println("  VALVE CLOSED  ");
104
  Serial.println("   TARGET HIT   ");
105

106
}
107

108
void printBanner(int bannerdelay)
109
{
110
  lcd.setCursor(0,0);                     
111
  lcd.print("  Waschmittel   ");
112
  lcd.setCursor(0,1);  
113
  lcd.print("  wird dosiert  ");
114
  delay(bannerdelay);
115
}
116

117
void printLabels()
118
{
119
  lcd.setCursor(0,0);
120
  lcd.print("Ziel: ");
121
  lcd.setCursor(0,1);
122
  lcd.print("Aktuell: ");
123
}
124

125
// read the buttons
126
int read_LCD_buttons()
127
{
128
  adc_key_in = analogRead(0);
129
  /*  OLD BUTTONS at 3.3V
130
  if (adc_key_in > 1000) return btnNONE;
131
  if (adc_key_in < 50)   return btnRIGHT; 
132
  if (adc_key_in < 195)  return btnSELECT;
133
  if (adc_key_in < 380)  return btnUP;
134
  if (adc_key_in < 555)  return btnDOWN;
135
  if (adc_key_in < 790)  return btnLEFT; 
136
 */
137

138
 if (adc_key_in > 1000) return btnNONE;  
139
 if (adc_key_in < 50)   return btnRIGHT; 
140
 if (adc_key_in < 195)  return btnUP;
141
 if (adc_key_in < 380)  return btnDOWN;
142
 if (adc_key_in < 555)  return btnLEFT;
143
 if (adc_key_in < 790)  return btnSELECT; 
144

145
  return btnNONE;
146
}
147

148
void dowork()
149
{
150

151
  //Serial.print("Freq: "); Serial.println(flowrate);        //Uncomment these two lines to monitor the freq/pulses
152
  //Serial.print("Pulses: "); Serial.println(pulses, DEC);
153
  float liters = pulses;
154
  liters /= 7.5;
155
  liters /= 60.0;
156
  
157
  current_volume = liters;
158
  
159
  //Debug Messaging
160
  Serial.print("Cur: "); Serial.println(current_volume);
161
  Serial.print("Tar: "); Serial.println(target_volume);
162
  
163
  //Print the target volume value in litres
164
  lcd.setCursor(11,0);
165
  lcd.print(target_volume,2);
166
  lcd.setCursor(15,0);
167
  lcd.print("L");
168

169
  //Print the current volume value in litres
170
  lcd.setCursor(11,1);            
171
  lcd.print(current_volume,2);
172
  lcd.setCursor(15,1);
173
  lcd.print("L");
174

175
  lcd_key = read_LCD_buttons();    // read the buttons
176
  
177

178
  switch (lcd_key)               // depending on which button was pushed, we perform an action
179
  {
180
  case btnRIGHT:
181
    {
182
     if (digitalRead(SOLENOIDPIN == HIGH))
183
     {
184
             digitalWrite(SOLENOIDPIN,LOW);       //STOP FLOW
185
     }
186
      
187

188
      Serial.println("Solenoid Closed");
189
      break;
190
    }
191

192
  case btnLEFT:
193
    {
194
     if (digitalRead(SOLENOIDPIN == LOW))
195
     {
196
             digitalWrite(SOLENOIDPIN,HIGH);       //START FLOW
197
     }
198
      
199

200
      Serial.println("Solenoid Open");
201
      
202
      break;
203
    }
204

205
  case btnUP:
206
    {
207
      if (target_volume >= hltSIZE)  //don't go larger than the size of the vessel
208
      {
209
        target_volume = hltSIZE;
210
        break;
211
      }
212
      else
213
      {
214
        target_volume += 0.01;
215
        break;
216
      }
217

218
      break;
219
    }
220

221
  case btnDOWN:
222
    {
223
      if (target_volume <= 0)      //don't go below zero
224
      {
225
        target_volume = 0;
226
        break; 
227
      }
228
      else
229
      {
230
        target_volume -= 0.01;
231
      }
232
      break;
233
    }
234
   
235

236
  case btnNONE:
237
    {
238
      break;
239
    }
240
  }
241

242
}



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ß
ebonsai
Gast #4985512
Lesenswert?

Wie du eine Taste abfragen kannst, das solltest du selbst herausfinden 
können. Dazu gibt es ja auch reichlich Code-Beispiele (es sind nur zwei 
zeilen nötig!).

Wenn du das nicht alleine schaffst, dann hast du dir das falsche Hobby 
ausgesucht. Deswegen versuche es erst mal selbst. Am besten zunächst mit 
einem viel kleineren Programm, dass auf Tastendruck eine LED 
einschaltet.

Das schaffst du schon...

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren