Die Idee geht auf den Artikel Countdown Zähler in der Raspberry Pi Geek 11-12.2017 Seite 58 zurück.
Der MAX7221 ist ein sehr interessanter Display Driver IC mit SPI Schnittstelle.
DIE VQB23 sind alte DDR Doppel LED Displays mit gemeinsamer Kathode.
In der Schaltung ist noch eine gn LED für die Sekunden Anzeige und eine rt Status LED
sowie eine Taste zum Beenden des Uhr Programms eingetragen.
Die RTC mit DS 1307 und der Temperatur Sensor DS18B20 sind im Programm noch nicht aktiviert.
Das C Programm besteht aus vielen Code Schnippsel für Tips zur Verbesserung wäre ich sehr dankbar.
Den beschriebenen Countdown Zähler habe ich nicht zum laufen bekommen.
In der Schaltung sind die LED Displays falsch eingetragen der SPI Bus wird nicht initialisiert.
Es wird ein 2017-11-29-raspbian-stretch-lite.img benutzt welches dann zuerst aktualisiert wurde.
Die Installation von Raspbian Stretch lief nach dem folgenden Muster auf einem Linux Pc ab.
Dann die SD Karte aus dem Pc nehmen in den RasPi stecken und einschalten.
Anmelden als pi - raspberry ACHTUNG: es ist noch die ami Tastatur aktiv also z für das y beim Passwort.
sudo raspi-config
1. Passwort von pi ändern.
2. Die 4 Locales einrichten.
3. Den ssh Server einschalten
4. reboot
Ab hier dann alles über ssh mit Hilfe von putty.
Die ersten Schritte um den SPI und den 1wire Bus im RasPi einzuschalten.
Nach einem reboot ist im Geräteverzeichnis das SPI Device zu finden.
Um das Programm benutzen zu können muss noch wiringPi Installiert werden.
sudo apt install git-core
git clone git://git.drogon.net/wiringPi
cd wiringPi
git pull origin
./build
gpio -v
gpio readall
Die Übersetzung und der Start des Programms.
Das Programm
#include <wiringPi.h>
#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <time.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>
#define Sek_LED_Pin 4 // wiringPi-Pin 4 GPIO23 BCM Pin 16
#define Taster_LED_Pin 6 // wiringPi-Pin 6 GPIO25 BCM Pin 22
#define Taster_Pin 5 // wiringPi-Pin 5 GPIO24 BCM Pin 18
// Globale Variablen
char zeit [5];
char sec [3];
int sek;
void uhr ()
{
time_t rawtime;
struct tm * timeinfo;
time ( &rawtime );
timeinfo = localtime ( &rawtime );
strftime (zeit,5,"%H%M",timeinfo); // Hier wird die Zeit für die LED Uhr in Stunde und Minute erzeugt zb. 1630
strftime (sec,3,"%S",timeinfo); // Hier werden die Sekunden für die Aktivierung der LED Anzeige erzeugt.
}
void blink ()
{
digitalWrite(Sek_LED_Pin, HIGH);
delay(200);
digitalWrite(Sek_LED_Pin, LOW);
delay(800);
}
void tasten ()
{
printf("Raspberry Pi Taster-Programm mit wiringPi\n");
if(wiringPiSetup() == -1) // wiringPi initialisieren
exit (EXIT_FAILURE); // Fehler? -> Programmende
pinMode(Taster_LED_Pin, OUTPUT); // Pin als Ausgang nutzen
pinMode(Sek_LED_Pin, OUTPUT); // Pin als Ausgang nutzen
pinMode(Taster_Pin, INPUT); // Pin als Eingang nutzen
}
static void pabort(const char *s)
{
perror(s);
abort();
}
static const char *device = "/dev/spidev0.0";
static uint8_t mode;
static uint8_t bits = 8;
static uint32_t speed = 500000;
static void matrixwrite(int fd, unsigned char max_address, unsigned char max_data)
{
uint8_t tx[] = { max_address, max_data, };
write(fd, tx, 2);
}
static void initspi(int fd)
{
int ret = 0;
/** spi mode **/
ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
if (ret == -1)
pabort("can't set spi mode");
ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);
if (ret == -1)
pabort("can't get spi mode");
/** bits per word **/
ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
if (ret == -1)
pabort("can't set bits per word");
ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
if (ret == -1)
pabort("can't get bits per word");
/** max speed hz **/
ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
if (ret == -1)
pabort("can't set max speed hz");
ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
if (ret == -1)
pabort("can't get max speed hz");
}
int main(int argc, char *argv[])
{
int fd;
fd = open(device, O_RDWR);
if (fd < 0)
pabort("can't open device");
initspi(fd);
printf("---------------------------------------\n");
printf("spi mode: %d\n", mode);
printf("bits per word: %d\n", bits);
printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000);
printf("---------------------------------------\n");
uint8_t col; // Column
//All leds off.
for (col = 1; col <= 8; col++) { matrixwrite(fd, col, 0); }
// Initialize Matrix
matrixwrite(fd, 0x0C, 0x01); // Normal operation
matrixwrite(fd, 0x0B, 0x03); // Scan Limit (all digits)
matrixwrite(fd, 0x0A, 0x07); // Intensity
matrixwrite(fd, 0x09, 0xFF); // Decode mode (00=off FF=on)
tasten();
int input_value;
while(1) {
input_value = digitalRead(Taster_Pin); // Taster-Status lesen
if(input_value == 0) // Wenn Taster Status gleich LOW oder 0 bzw. nicht gedrückt.
{
digitalWrite(Taster_LED_Pin, HIGH);
}
else // Wenn Taster Status gleich HIGH oder 1 bzw. gedrückt.
{
digitalWrite(Taster_LED_Pin, LOW);
delay(1000);
break;
}
uhr();
sek = atoi (sec);
if ( sek <= 58)
{
blink();
}
else
{
matrixwrite(fd,0x01,(zeit[0]));
matrixwrite(fd,0x02,(zeit[1]));
matrixwrite(fd,0x03,(zeit[2]));
matrixwrite(fd,0x04,(zeit[3]));
delay(1000);
} // Ende if
} // Ende while
//All leds off.
for (col = 1; col <= 8; col++) { matrixwrite(fd, col, 0); }
close(fd);
return 1;
}
Alles anzeigen
Der Schaltplan