Forum: Mikrocontroller und Digitale Elektronik Dosieranlage mit Arduino - kurze Frage


von eBonsai (Gast)


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

von Regelcop (Gast)


Lesenswert?

eBonsai schrieb:
> Mein anderes Problem wäre,

... dass du den Bereich "Wichtige Regeln - erst lesen, dann posten!"
nicht liest, nicht verstehst, oder nicht danach handelst, oder
alles zusammen.

(--> Längeren Sourcecode nicht im Text einfügen, sondern als 
Dateianhang)

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

eBonsai schrieb:
> Gibts dafür Abhilfe?
Mach einen PullDown an den Pin. Denn der ist laut Datenblatt bei einem 
Reset hochohmig.

von Stefan F. (Gast)


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...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.