Hey Leute,
ich bastle gerade an einer LED Matrix, die in Echtzeit die Abfahrten des lokalen Busunternehmens anzeigt.
Dafür verwende ich einen Arduino mit Ethernet Shield und einen modifizierten XML-Parser.
Das Script holt sich die Daten von folgender Website: http://www.ivb.at/smartinfo/ivb_smartinfo_kernel.php?olifServerId=84&autorefresh=20&default_autorefresh=20&routeId=&stopId=Absam Dorf&optDir=-1&nRows=4&showArrivals=n&optTime=now&time=&allLines=y&app=sionline.
Je nachdem, ob im Link Rows=1 oder Rows=4 steht, werden eine Busabfahrt (ein XML Array) oder 4 Abfahrten (4 Arrays) angezeigt.
Das Script holt sich diese Daten und spielt sie auf die LED Matrix (Foto 1).
Solange es bei einer Abfahrt (Rows=1) bleibt, funktioniert alles wunderbar.
Die Tafel wäre aber eigentlich dafür gedacht, 4 Abfahrten (Rows=4) anzuzeigen.
Dabei ergibt sich aber das Problem, dass alle Abfahrten auf der LED Matrix in einer Zeile (Foto 2) und nicht so wie geplant in vier Zeilen (Foto 3) angezeigt werden.
Im Prinzip müsste man also die einzelnen Strings trennen, z.B.:
D Kurhaus 18:36 = String 1 E Hauptbahnhof 4 min =String 2...Im Serial Monitor werden die Daten auch schön säuberlich in 4 Zeilen ausgegeben, z.B.:
Linie: D Ziel: H Abfahrt: 2 min
Linie: E Ziel: K Abfahrt: 16 min
Linie: D Ziel: H Abfahrt: 16 min
Linie: D Ziel: H Abfahrt: 10:51
Hier mal der Code:
#include <SPI.h>
#include <string.h>
#include <Ethernet.h>
#include "HT1632.h"
#define MAX_STRING_LEN 20
#define DATA 2
#define WR 3
#define CS 4
#define CS2 5
#define CS3 6
#define CS4 7
HT1632LEDMatrix matrix = HT1632LEDMatrix(DATA, WR, CS, CS2, CS3, CS4);
char tagStr[MAX_STRING_LEN] = "";
char dataStr[MAX_STRING_LEN] = "";
char tmpStr[MAX_STRING_LEN] = "";
char endTag[3] = {
'<', '/', '\0'};
int len;
boolean tagFlag = false;
boolean dataFlag = false;
byte mac[] = {
0x90, 0xA2, 0xDA, 0x0D, 0x52, 0xBD };
byte ip[] = {
192, 168, 2, 3 };
byte server[] = {
83, 175, 126, 90 };
EthernetClient client;
void setup()
{
Serial.begin(9600);
matrix.begin(HT1632_COMMON_16NMOS);
Serial.println("Starting IVB.at");
Serial.println("connecting...");
Ethernet.begin(mac, ip);
delay(0);
if (client.connect(server, 80)) {
Serial.println("connected");
client.println("GET /smartinfo/ivb_smartinfo_kernel.php?olifServerId=84&autorefresh=20&default_autorefresh=20&routeId=&stopId=Absam%20Dorf&optDir=-1&nRows=4&showArrivals=n&optTime=now&time=&allLines=y&app=sionline HTTP/1.0");
client.println("Host: www.ivb.at");
client.println();
delay(10);
}
else {
Serial.println("connection failed");
matrix.clearScreen();
matrix.setTextSize(1);
matrix.setTextColor(1);
{
matrix.setCursor(0, 0);
matrix.print("Bitte beachten");
matrix.setCursor(0, 8);
matrix.print("Fahrplan");
matrix.writeScreen();
}
delay(100);
}
}
void loop() {
// Read serial data in from web:
while (client.available()) {
serialEvent();
}
if (!client.connected()) {
//Serial.println();
//Serial.println("Disconnected");
client.stop();
// Time until next update
//Serial.println("Waiting");
for (int t = 1; t <= 15; t++) {
delay(1000); // 1 minute
}
if (client.connect(server, 80)) {
//Serial.println("Reconnected");
client.println("GET /smartinfo/ivb_smartinfo_kernel.php?olifServerId=84&autorefresh=20&default_autorefresh=20&routeId=&stopId=Absam%20Dorf&optDir=-1&nRows=4&showArrivals=n&optTime=now&time=&allLines=y&app=sionline HTTP/1.0");
client.println("Host: www.ivb.at");
matrix.clearScreen();
client.println();
delay(0);
}
else {
Serial.println("Reconnect failed");
}
}
}
// Process each char from web
void serialEvent() {
// Read a char
char inChar = client.read();
//Serial.print(".");
if (inChar == '<') {
addChar(inChar, tmpStr);
tagFlag = true;
dataFlag = false;
}
else if (inChar == '>') {
addChar(inChar, tmpStr);
if (tagFlag) {
strncpy(tagStr, tmpStr, strlen(tmpStr)+1);
}
// Clear tmp
clearStr(tmpStr);
tagFlag = false;
dataFlag = true;
}
else if (inChar != 10) {
if (tagFlag) {
// Add tag char to string
addChar(inChar, tmpStr);
// Check for </XML> end tag, ignore it
if ( tagFlag && strcmp(tmpStr, endTag) == 0 ) {
clearStr(tmpStr);
tagFlag = false;
dataFlag = false;
}
}
if (dataFlag) {
// Add data char to string
addChar(inChar, dataStr);
}
}
// If a LF, process the line
if (inChar == 10 ) {
/*
Serial.print("routeStr: ");
Serial.println(directionStr);
Serial.print("directionStr: ");
Serial.println(directionStr);
*/
// Find specific tags and print data
if (matchTag("<time>")) {
Serial.print(" Abfahrt: ");
Serial.print(dataStr);
String stringOne = dataStr;
Serial.println(stringOne);
String stringTwo = stringOne;
stringTwo.replace("min","'");
stringTwo.replace(":","");
matrix.setTextSize(1);
matrix.setTextColor(1);
{
matrix.setCursor(24, 0);
matrix.println(stringTwo);
matrix.writeScreen();
}
}
if (matchTag("<direction>")) {
Serial.print(" Ziel: ");
Serial.print(dataStr);
char mostSignificantDigit = dataStr[0];
matrix.setTextSize(1);
matrix.setTextColor(1);
{
matrix.setCursor(16, 0);
matrix.println(mostSignificantDigit);
matrix.writeScreen();
}
}
if (matchTag("<route>")) {
Serial.print(" Linie: ");
Serial.print(dataStr);
matrix.setTextSize(1);
matrix.setTextColor(1);
{
matrix.setCursor(0, 0);
matrix.print(dataStr);
matrix.writeScreen();
}
}
// Clear all strings
clearStr(tmpStr);
clearStr(tagStr);
clearStr(dataStr);
// Clear Flags
tagFlag = false;
dataFlag = false;
}
}
/////////////////////
// Other Functions //
/////////////////////
// Function to clear a string
void clearStr (char* str) {
int len = strlen(str);
for (int c = 0; c < len; c++) {
str[c] = 0;
}
}
//Function to add a char to a string and check its length
void addChar (char ch, char* str) {
char *tagMsg = "<TRUNCATED_TAG>";
char *dataMsg = "-TRUNCATED_DATA-";
// Check the max size of the string to make sure it doesn't grow too
// big. If string is beyond MAX_STRING_LEN assume it is unimportant
// and replace it with a warning message.
if (strlen(str) > MAX_STRING_LEN - 2) {
if (tagFlag) {
clearStr(tagStr);
strcpy(tagStr,tagMsg);
}
if (dataFlag) {
clearStr(dataStr);
strcpy(dataStr,dataMsg);
}
// Clear the time buffer and flags to stop current processing
clearStr(tmpStr);
tagFlag = false;
dataFlag = false;
}
else {
// Add char to string
str[strlen(str)] = ch;
}
}
// Function to check the current tag for a specific string
boolean matchTag (char* searchTag) {
if ( strcmp(tagStr, searchTag) == 0 ) {
return true;
}
else {
return false;
}
}
BTW ich hab das Ganze schon mal im Englischen Forum gepostet, aber leider keine wirklich brauchbare Antwort bekommen...
Ich hoffe ihr könnt mir helfen! Sitze wirklich schon Wochen über dem Script und finde einfach keine Lösung!
Habe es schon mit diversen String-Funktionen probiert, aber nicht wirklich erfolgreich!