Arduino Uno & Wasserstandsensor auf LCD und SD Karte: kryptische Zeichen im LCD?

Hallo!
Ich versuche mich gerade an diverse Teilprojekte heranzuarbeiten. Am Anfang steht ein Wasserstandssensor, der die Daten auf SD Karte speichert und im LCD anzeigt.

Später soll das ganze per ESP8266/12 gehen, um dann irgendwann (wahrscheinlich existiere ich dann nicht mehr :frowning: ) erst ein semiautomatisches Bewässerungssystem, dann in ein automatisches Bewässerungssystem und dann in ein Kontrollsystem für ein Gewächshaus (en miniature) werden.

Naja, aber im Moment stockt es schon am Anfang. Ich habe erst den Wasserstandsensor getestet, dann die SD Karte ohne irgendwas, dann den Sensor mit LCD - bis hierhin funktionierte alles so, wie erwartet.

Dann war ich so "tollkühn" SD Karten und LCD zu kombinieren. Die SD Karte und die serielle Ausgabe funktionieren - nur die LCD Anzeige gibt kryptische Zeichen aus.

Ich hatte auch versucht, die LCD Ausgabe in eine separate Funktion auszulagern, die die x, y Koordinate übergibt, eine Bool.Wert und den auszugebenden Text.

Ich habe für dieses Vorhaben diverse Vorlagen kombiniert.

Meine Fragen:

  1. warum kommt da was kryptisches aufm LCD raus? - Primäre FRAGE

  2. wie kann ich das String Objekt umgehen und mit einem Text aus 16 chars arbeiten? (Hab's versucht, aber immer Fehlermeldungen bekommen, vor allem bei der Umwandlung von int -> char

  3. warum bekomme ich eine Warnmeldung "In function 'void loop()': 84:6: note: initializing argument 4 of 'void write_LCD(int, int, bool, String)'"?

Danke.

Der Code:

//www.elegoo.com
//2016.12.9
//Modified by ak

/*
  LiquidCrystal Library - Hello World

 This example code is in the public domain.

 http://www.arduino.cc/en/Tutorial/LiquidCrystal
 */

// include the library code:
#include <LiquidCrystal.h>
#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include "RTClib.h"

const int chipSelect = 10; //10 is default by shield, but normally on Pin 4
int interval = 20;  //Log to SD Card every 5 seconds

long timer;
String timestring;
String mvalue;

RTC_DS1307 rtc;

int adc_id = 0;
int HistoryValue = 0;
char printBuffer[128];

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

void setup() {
  Serial.begin(9600);
  delay(1000);
  lcd.begin(16, 2);
  Serial.println("Initializing SD card...");
  if (!SD.begin(chipSelect)) {
    Serial.println("SD Card error");
    return;
  }
  write_LCD(0,0, true, "card initialized");
  Serial.println("card initialized");
  delay(1000);
  if (! rtc.begin()) {
    Serial.println("No RTC found");
    write_LCD(0,0, true, "No RTC found");
    
  } else {
    Serial.println("RTC clock found");
    write_LCD(0,0, true, "RTC found");
  }
  if (! rtc.isrunning()) {
    Serial.println("RTC is not configured");
    write_LCD(0,0, true, "RTC not config");
  }
  // set up the LCD's number of columns and rows:
  delay(1000);
  // Print a message to the LCD.
  lcd.print("Hello, World!");
  Serial.println("Hello World");
}


void loop() {
    int value = analogRead(adc_id); // get adc value
    if(((HistoryValue>=value) && ((HistoryValue - value) > 4)) || ((HistoryValue<value) && ((value - HistoryValue) > 10)))
    {
      sprintf(printBuffer,"ADC%d level is %d\n",adc_id, value);
      Serial.print(printBuffer);
      mvalue = String(value);
      write_LCD(0,0,true, "Feuchte");
      write_LCD(0,1,false, value);
      HistoryValue = value;
      get_time();
      write_data();
    }
}

void write_LCD(int x, int y, bool clearIt, String text) {
  if (clearIt) {
    lcd.clear();
  }
  lcd.setCursor(x,y);
  lcd.print(text);
}

void get_time(){ //Read Time from RTC
  DateTime now = rtc.now();
  timestring = now.day();
  timestring += "-";
  timestring += now.month();
  timestring += "-";
  timestring += now.year();
  timestring += " ";
  timestring += now.hour();
  timestring += ":";
  timestring += now.minute();
  timestring += ":";
  timestring += now.second();
  Serial.println(timestring);
}

void write_data() { //Write to SD card
  String dataString = mvalue + "," + timestring;
  File dataFile = SD.open("datalog.txt", FILE_WRITE);
  if (dataFile) {
    dataFile.println(dataString);
    dataFile.close();
    Serial.println(dataString);
  }
  else {
    Serial.println("error writing datalog.txt");
  }
}

Diene kryptischen zeichen liegen vermutlich daran, dass du die SPI-Pins doppelt verwendest. 1 mal für die SD-Card und für dein Display. Du musst die Pins für dein LCD anders definieren. Ohne D10, D11 und D12.

Das solltest du besser abstellen und nimm einfach ein Display mit I2C-Adapter. Da brauchst du nur 2 Pins, SCL und SDA (A5 und A4) und natürlich die Spannung VCC und GND.

Und poste bitte mal einen Link (Hyperlink, kann man anklicken) deiner LCD-Library. Da kann man dann sehen, wo dein Fehler liegt.

Hi

SPI kann man schon auf mehreren Geräten zusammen nutzen - dafür ist's ja ein Bus!
Nur muß jedes Gerät eine eigene SlaveSelect-Leitung haben.
MISO, MOSI und Takt brauchen alle SPI-Teilnehmer.

MfG

postmaster-ino:
Hi

SPI kann man schon auf mehreren Geräten zusammen nutzen - dafür ist's ja ein Bus!
Nur muß jedes Gerät eine eigene SlaveSelect-Leitung haben.
MISO, MOSI und Takt brauchen alle SPI-Teilnehmer.

MfG

Was hat das mit dem Display zu tun, welches parallel betrieben wird ?

  1. warum bekomme ich eine Warnmeldung "In function 'void loop()': 84:6: note: initializing argument 4 of 'void write_LCD(int, int, bool, String)'"?

Zumindest den Punkt kann ich erklären, deine Funktion write_LCD() erwartet als 4. Parameter einen String, du übergibst aber ein int. Irgendwie stimmen die Zeilennummern nicht mehr überein, den Fehler findest du in Zeile 76, laut deinem angezeigten Sketch:

write_LCD(0,1,false, value);

2 Zeilen vorher lässt du den int zwar in einen String umwandeln, übergibst aber die falsche Variable. Das man Strings besser nicht nutzen sollte, scheinst du ja schon zu wissen.

Hi

HotSystems:
Was hat das mit dem Display zu tun, welches parallel betrieben wird ?

Schnellschuss - Hatte 'nur' SD, SPI-Pins doppelt beutzt und Display gelesen - zusätzlich I²C, Da hatte ich mir schon meinen Teil zusammen gereimt und auf eine gemeinsame Select-Leitung getippt.

Aber: Ja, mit Blick in den Sketch wäre Einem wohl die Zeile "LiquidCrystal lcd(7, 8, 9, 10, 11, 12);" aufgefallen, Die wohl 4bit-Betrieb andeutet.

Mit zusätzlich gelobter Besserung verbleibe ich
MfG

postmaster-ino:
Mit zusätzlich gelobter Besserung verbleibe ich

Alles klar, kann ja mal passieren. :wink:

Hallo!
Vielen Dank für das Feedback.
Es tut mir leid, dass ich erst jetzt antworte. Ich hatte gedacht über neue Antworten informiert zu werden. Keine diesbezüglich, keine Reaktionen, so dachte ich... :frowning:

@HotSystems: Ich schaue mir meinen Aufbau nochmal an und ändere die Pins. Auch werde ich mal mein neues I2C Display austesten :wink:
Ich scheine übrigens folgende Library zu nutzen: https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads/

@wapjoe: Danke. Doch wie löse ich das Problem, dass die Funktion einmal einen Integer zur Ausgabe bekommt und einmal einen String? Der String schien mir der kleinste gemeinsame Nenner zu sein..

@postmaster-ino Bis zu SlaveSelect hatte ich noch halbwegs verstanden, was gemeint war.

ich mache mich jetzt mal über den SPI schlau und eben so über I2C, interupts and timers...

Danke!

Die von dir verlinkte Library ist sehr aktuell und auch für I2C geeignet.
Das sollte dann mit einem LCD und I2C auch funktionieren.
Da müsste dann solch einer oder ähnlicherAdapter drauf sein.