I wanted to include a datalogger to my simple brewing controller. I used an arduino UNO together with an LCD keypad shield which unfortunately uses the PINs for SPI.
When checking the forum I figuered there should be a Soft SPI which can be used in such cases but unfortunately I cant get the SD card initialized.
Has someone an idea what is wrong with my code?
code:
/*******************************
- Start: Grüner Button (ca. 6s betätigen bis Heizen erscheint)
- Reset: Roter Knopf (ca. 6s betätigen bis Reset erscheint) kann jederzeit betätigt werden und setzt das Programm zurück
- Temperaturregelung +/- 0.3°C
- Timer in min bei den Haltezeiten
Maischeprogramm:
- Heizen auf 50°C
- Einmaisen 15 min
- Heizen auf 62°C
- Maltoserast 60 min
- Heizen auf 72°C
- Zuckerrast 15 min
- Heizen auf 78°C
******************************/
//Libraries:
#include <LiquidCrystal.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <SD.h>
#include <SPI.h>
#include <SoftSPI.h>
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
float Celsius = 0;
float Fahrenheit = 0;
// Pin - Definitionen
const int pin_RS = 8; // LCD Pin
const int pin_EN = 9; // LCD Pin
const int pin_d4 = 4; // LCD Pin
const int pin_d5 = 5; // LCD Pin
const int pin_d6 = 6; // LCD Pin
const int pin_d7 = 7; // LCD Pin
const int pin_BL = 10; // LCD Pin
LiquidCrystal lcd( pin_RS, pin_EN, pin_d4, pin_d5, pin_d6, pin_d7);
int CS_PIN = A4; //Pin für SD Karte
const int RelaisPin = 3; //Heizung
int x; //Pin für Taster
SoftSPI mySPI(A1, A2, A3); // MOSI,MISO,SCK
File Textdatei;
//Switch Variables:
int state_s1 = 0;
//Intervalle:
long interval1 = 6000; //Intervall Temperaturabfrage Heizung (6s)
long interval2 = 900000; //Intervall Einmaischen (15min)
long interval3 = 3600000; //Intervall Maltoserast (60min)
long interval4 = 900000; //Intervall Zuckerrast (15min)
long previousMillis2 = 0; //Speicher der letzten Zeit vor umschalten nächsten State
long previousMillis3 = 0; //Speicher der letzten Zeit vor umschalten nächsten State
//Temperaturen:
const int Temp1 = 50; //50
const int Temp2 = 62; //62
const int Temp3 = 72; //72
const int Temp4 = 78; //78
//Temperatur Funktion
void Temp_loop()
{
int i;
float tempData[3];
for(i=0; i<3; i++)
{
sensors.requestTemperatures();
tempData[i] = sensors.getTempCByIndex(0);
}
Celsius = (tempData[0] + tempData[1] + tempData[2]) / 3;
//Celsius = sensors.getTempCByIndex(0);
Fahrenheit = sensors.toFahrenheit(Celsius);
// set the cursor to column 0, line 1
lcd.setCursor(0, 1);
lcd.print(Celsius);
Serial.println(Celsius);
lcd.print("C");
// Print State
lcd.setCursor(0, 0);
switch(state_s1)
{
case 0:
lcd.clear();
lcd.print("Reset");
break;
case 1:
lcd.print("Start");
break;
case 2:
lcd.print("Heizen auf 50C");
break;
case 3:
lcd.print("Einmaischen ");
break;
case 4:
lcd.print("Heizen auf 62C");
break;
case 5:
lcd.print("Maltoserast ");
break;
case 6:
lcd.print("Heizen auf 72C");
break;
case 7:
lcd.print("Zuckerrast ");
break;
case 8:
lcd.print("Heizen auf 78C");
break;
default:
lcd.print("Reset");
break;
}
Serial.println(Celsius);
}
void SPI_loop()
{
static uint8_t v = 0;
Serial.print("Sending value: ");
Serial.print(v, HEX);
uint8_t in = mySPI.transfer(v);
Serial.print(" Got value: ");
Serial.print(in, HEX);
Serial.println(v == in ? " PASS" : " FAIL");
delay(100);
v++;
}
void button_loop()
{
x = analogRead (0);
}
// Setup Befehle
void setup()
{
pinMode (RelaisPin, OUTPUT);
mySPI.begin();
pinMode(CS_PIN, OUTPUT);
Serial.begin(9600);
Serial.println("Debugging is ON");
lcd.begin(16, 2);
Serial.println("Initialisiere SD-Karte");
if (!SD.begin(A4)) { // Wenn die SD-Karte nicht (!SD.begin) gefunden werden kann, ...
Serial.println("Initialisierung fehlgeschlagen!"); // ... soll eine Fehlermeldung ausgegeben werden. ....
return;
}
Serial.println("Initialisierung abgeschlossen"); // ... Ansonsten soll die Meldung "Initialisierung abgeschlossen." ausgegeben werden.
Textdatei = SD.open("Ansatz.txt", FILE_WRITE); // An dieser Stelle wird die Textdatei erstellt. Unsere Textdatei soll "test" heißen und im Format ".txt" (Text) erstellt werden.
}
// State machine Zustäbde
void SM_s1()
{
unsigned long currentMillis;
Temp_loop();
button_loop();
SPI_loop();
//State Machine
switch (state_s1)
{
case 0: //RESET!
digitalWrite (RelaisPin, LOW);
state_s1 = 1;
break;
case 1: //Start
//Warten bis der Schalter aktiviert wird
Temp_loop();
if (x >600 && x < 800)
{
Serial.println("State 1, Start");
state_s1 = 2;
}
break;
case 2: //Heizen
Temp_loop();
currentMillis = millis();
digitalWrite (RelaisPin, HIGH);
Serial.println("State 2, Heizen");
if(x < 600)
{
state_s1 = 0;
}
if ((Celsius) - Temp1 > 0)
{
previousMillis2 = currentMillis;
Serial.println("State 3, Einmaischen");
lcd.clear();
previousMillis3 = millis();
state_s1 = 3;
}
break;
case 3: //Einmaischen
Temp_loop();
currentMillis = millis();
lcd.print (((interval2 + previousMillis3) / 60000)- (currentMillis/60000));
lcd.print ("m");
Serial.println("State 3, Einmaischen");
if(x < 600)
{
state_s1 = 0;
}
if (Celsius - Temp1 > 0.3)
{
digitalWrite (RelaisPin, LOW);
Serial.println("State 3, Einmaischen Kühlen");
}
if (Temp1 - Celsius > 0.3)
{
digitalWrite (RelaisPin, HIGH);
Serial.println("State 3, Einmaischen, Heizen");
}
if (currentMillis- previousMillis2 > interval2)
{
Serial.println("State 4, Heizen 2");
lcd.clear();
state_s1 = 4;
}
break;
case 4: //Heizen 2
Temp_loop();
digitalWrite (RelaisPin, HIGH);
Serial.println("State 4, Heizen 2");
if(x < 600)
{
state_s1 = 0;
}
if (Celsius - Temp2 > 0)
{
previousMillis2 = millis();
Serial.println("State 5, Maltoserast");
lcd.clear();
previousMillis3 = millis();
state_s1 = 5;
}
break;
case 5: //Maltoserast
Temp_loop();
currentMillis = millis();
lcd.print (((interval3 + previousMillis3) / 60000)- (currentMillis/60000));
lcd.print ("m");
Serial.println("State 5, Maltoserast");
if(x < 600)
{
state_s1 = 0;
}
if (Celsius - Temp2 > 0.3)
{
digitalWrite (RelaisPin, LOW);
Serial.println("State 5, Maltoserast Kühlen");
}
if (Temp2 - Celsius > 0.3)
{
digitalWrite (RelaisPin, HIGH);
Serial.println("State 5, Maltoserast, Heizen");
}
if (currentMillis- previousMillis2 > interval3)
{
Serial.println("State 6, Heizen 3");
lcd.clear();
state_s1 = 6;
}
break;
case 6: //Heizen 3
Temp_loop();
digitalWrite (RelaisPin, HIGH);
Serial.println("State 6, Heizen 3");
if(x < 600)
{
state_s1 = 0;
}
if (Celsius - Temp3 > 0)
{
previousMillis2 = millis();
Serial.println("State 6, Zuckerrast");
lcd.clear();
previousMillis3 = millis();
state_s1 = 7;
}
break;
case 7: //Zuckerrast
Temp_loop();
currentMillis = millis();
lcd.print (((interval4 + previousMillis3) / 60000)- (currentMillis/60000));
lcd.print ("m");
Serial.println("State 7, Zuckerrast");
if(x < 600)
{
state_s1 = 0;
}
if (Celsius - Temp3 > 0.3)
{
digitalWrite (RelaisPin, LOW);
Serial.println("State 7, Zuckerrast Kühlen");
}
if (Temp3 - Celsius > 0.3)
{
digitalWrite (RelaisPin, HIGH);
Serial.println("State 7, Zuckerrast, Heizen");
}
if (currentMillis- previousMillis2 > interval4)
{
Serial.println("State 8, Heizen 4");
lcd.clear();
state_s1 = 8;
}
break;
case 8: //Heizen 4
Temp_loop();
digitalWrite (RelaisPin, HIGH);
Serial.println("State 8, Heizen 4");
if(x < 600)
{
state_s1 = 0;
}
if (Celsius - Temp4 > 0)
{
previousMillis2 = millis();
Serial.println("Maische Läutern");
lcd.clear();
state_s1 = 9;
}
break;
case 9: //Reset
lcd.clear();
state_s1 = 0;
break;
default: //Zurücksetzten
Serial.println("default");
digitalWrite (RelaisPin, LOW);
lcd.clear();
state_s1 = 0;
break;
}
}
void loop()
{
SM_s1();
}