Hallo,
endlich habe ich es geschafft, den Code von ursprünglich einem LCD Display auf die Ausgabe auf LED Anzeigen aufzubohren. Der SAA1064 eigent sich dafür sehr gut, denn er kümmert sich ums Multiplexen der Anzeige, um die Strombegrenzung der Anzeigen und man kann die Anzeige auch über lediglich 4 Adern etwas abgesetzt vom µC platzieren. 1m Kabel sind überhaupt kein Problem.
youtube Videos gibts davon genug, nur keinen fertigen Code.
Deshalb hier mein Code:
/*
Example 39.3 - NXP SAA1064 I2C LED Driver IC Demo III
Displaying numbers on command
http://tronixstuff.com/tutorials > chapter 39
John Boxall July 2011 | CC by-sa-nc
*/
#include "Wire.h" // enable I2C bus
#include <LiquidCrystal_I2C.h>
#define sensorPin 0 // Verbunden mit LM35 Ausgang
#define DELAY1 10 // kurze Wartezeit beim Messen
#define DELAY2 500 // kurze Wartezeit beim Anzeigen
#define heaterPin 9 // Heizung-Pin
#define threshold 40 // Schalt-Temperatur für Lüfter (40 Grad Celsius)
#define hysterese 0.1 // Hysterese-Wert (0.1 Grad Celsius)
const int cycles = 50; // Anzahl der Messungen
LiquidCrystal_I2C lcd(0x20, 16, 2); // Adresse auf 0x27 für 16 Zeichen/2 Zeilen
byte saa1064 = 0x70 >> 1; // define the I2C bus address for our SAA1064 (pin 1 to GND)
int digits[12]={
63, 6, 91, 79, 102, 109, 125,7, 127, 111, 204, 0};
// these are the byte representations of pins required to display each digit 0~9, °C sign, and blank digit
// right hand digit 180° flip - DP ist used as ° symbol :-) 204 is °c for big C use 143
void setup()
{
lcd.init(); // LCD initialisieren
lcd.backlight(); // Hintergrundbeleuchtung aktivieren
pinMode(heaterPin, OUTPUT);
Wire.begin(); // start up I2C bus
delay(500);
initDisplay();
}
void initDisplay()
// turns on dynamic mode and adjusts segment current to 12mA
{
Wire.beginTransmission(saa1064);
Wire.write(B00000000); // this is the instruction byte. Zero means the next byte is the control byte
Wire.write(B01110111); // control byte (dynamic mode on, digits 1+3 on, digits 2+4 on, 21mA segment current
// left 111 is relevant for current left hand "1" 12mA, middle 6mA and right 3mA - so you can tewak it
Wire.endTransmission();
}
void clearDisplay()
{
Wire.beginTransmission(saa1064);
Wire.write(1); // start with digit 1 (right-hand side)
Wire.write(0); // blank digit 1
Wire.write(0); // blank digit 2
Wire.write(0); // blank digit 3
Wire.write(0); // blank digit 4
Wire.endTransmission();
}
void displayInteger(int num, int zero)
{
int hundred, ten, one;
// breakdown number into columns
hundred = num/100;
ten = (num-(hundred*100))/10;
one = num-((hundred*100)+(ten*10));
if (zero==1) // yes to leading zero
{
Wire.beginTransmission(saa1064);
Wire.write(1);
Wire.write(digits[hundred]);
Wire.write(digits[ten]+128); // 128 turns on DP
Wire.write(digits[one]);
Wire.write(digits[10]); // print position 10 from arry - °C
Wire.endTransmission();
delay(10);
}
else
if (zero==0) // no to leading zero
{
if (hundred==0) { hundred=11; }
if (hundred==0 && num<100) { hundred=16; }
if (ten==0 && num<10) { ten=16; }
Wire.beginTransmission(saa1064);
Wire.write(1);
Wire.write(digits[hundred]);
Wire.write(digits[ten]+128);
Wire.write(digits[one]);
Wire.write(digits[10]);
Wire.endTransmission();
delay(10);
}
}
void loop()
{
{
float resultTemp = 0.0;
for(int i = 0; i < cycles; i++){
int analogValue = analogRead(sensorPin);
float temperature = (5.07 * 100.0 * analogValue) / 1024; // reale Spannung Ub (theoretisch 5.00V)
resultTemp += temperature; // Aufsummieren der Messwerte
delay(DELAY1);
}
resultTemp /= cycles; // Berechnung des Durchschnitts
lcd.clear(); // clear-Methode löscht LCD Inhalt
lcd.print("Temp: "); // print-Methode schreibt LCD Inhalt
lcd.print(resultTemp);
lcd.setCursor(10, 0);
#if ARDUINO < 100
lcd.print(0xD0 + 15, BYTE); // Grad-Zeichen (Arduino 0022)
#else
lcd.write(0xD0 + 15); // Grad-Zeichen (Arduino 1.00)
#endif
lcd.print("C");
lcd.setCursor(0, 1); // setCorsor-Methode positioniert LCD-Cursor
lcd.print("Heizung: ");
{
delay(20);
}
clearDisplay();
{
displayInteger(resultTemp * 10 ,0); //for LED-Display x10 - DP is hardwired
delay(5);
if(resultTemp < (threshold - hysterese)) // Temperaturvergleich pos.
digitalWrite(heaterPin, HIGH); // Heizung anschalten
else if(resultTemp > (threshold + hysterese)) // Temperaturvergleich neg.
digitalWrite(heaterPin, LOW); // Heizung abschalten
lcd.print(digitalRead(heaterPin) == HIGH?"an":"aus");
delay(DELAY2);
}
}
}
Bei den Anzeigen handelt es sich um "Ostalgie"
Es sind Siebensegmentanzeigen des Typ VQA 28 Made in GDR 8)
Owohl ich den lichtstärksten Suffix F habe, sind die Dinger nicht besonders hell. Das ist auch der Symbolgröße von 17,9mm geschuldet. Deshalb bestrome ich die Dinger auch mit den max. möglichen 21mA, die der SAA1064 zuläßt
Die rechte Stelle ist kopfstehend montiert, um den Dezimalpunkt als "°" Zeichen verwenden zu können. Die Segmente habe ich so verschaltet, als würde die Anzeige richtig herum montiert sein, also wie vom Hersteller angegeben. Wenn man anders verdrahtet, ist Pos. 10 im Arry für die Anzeige von °C entsprechend anzupassen!
204 als kleines c oberhalb der Mitte finde ich optisch am besten. 143 erzeugt ein großes C
Im Zehner (3. Stelle) wird 128 addiert, da 128 den Dezimalpunkt aktiviert. Segment a=1, b=2, c=4 usw. Aufaddieren erzeugt dann das anzuzeigende Zeichen.
displayInteger(resultTemp * 10 ,0); hat folgenden Sinn: die Temperatur wird x10 genommen, da ich für das LED Display eine 3stellige ganze Zahl benötige - der Dezimalpunkt (+128) ist hart gesetzt und bewirkt wieder die Division durch 10 beim Betrachter
,0 bedeutet, den Integerwert auf eine ganze Zahl zu runden - null Nachkommastellen
Für das ursprüngliche 16x2 I2C LCD Display habe ich den Code zur Kontrolle drin gelassen.
Ich habe das Ganze, wie man am Code erkennen kann, zur Steuerung eines Wärmeschrankes genutzt. Das LCD war mir dort zu schlecht ablesbar.
Meine Frage ist nun, wie kann ich die PID_v1 Lib. hier noch mit einbinden? Pin 9, der Heizungs-Pin steuert über einen Transistor die LED eines Solid-State-Relay an.
So mit festem Schaltpunkt, wie ich es jetzt habe, steigt die Temparatur nach dem Abschalten bei 40°C noch auf 41,5°C an, da die Heizwiderstände noch Wärme abgeben. Dieses Überschwingen ist aber nicht gewünscht :~
Kann mir da jemand weiterhelfen?
Gruß Gerald