Page : | [ 1 ] | [ 2 ] | [ 3 ] | [ 4 ] |
On the router I wrote some PHP script that gets information from OpenWRT and sends it over the serial interface to the LCD board.
This script simply sends an arbitrary amount of "screens" of information to the board. A "screen" being 32 characters (for the 16x2 display).
The microcontroller (µC) then just checks that the data sent is a multiple of 32 and then just stores those screens that are then displayed when someone pushes the button.
The script runs via cron once per minute. The button is used to activate the display, which stays on long enough to show all the screens of information that are currently stored on the µC.
Here is the Arduino code for the µC:
#include <Wire.h>
#include <LiquidTWI2.h>
#include <SoftwareSerial.h>
#define ROWLEN 16
LiquidTWI2 lcd(0);
SoftwareSerial mySerial(9, 8); // RX, TX
volatile byte flag = 0;
const byte ledPin = 7;
const byte interruptPin = 2;
int byteCount = 0;
char readBuf[256];
char useBuf[256];
bool gotStart = false;
bool gotEnd = false;
int gotStartInterval = 5000;
unsigned long gotStartMillis = 0; // when got first char of serial stream
int currentScreen = 0;
int screenInterval = 5000;
unsigned long lastScreenMillis = 0;
int screens = 0;
int buttonInterval = 5000;
unsigned long buttonMillis = 0;
void setup() {
Serial.begin(9600);
mySerial.begin(2400); // tx 9 , rx 8 , unusable 10
pinMode(9, INPUT);
pinMode(ledPin, OUTPUT);
lcd.setMCPType(LTI_TYPE_MCP23017);
lcd.begin(16, 2);
lcd.setBacklight(LOW);
lcd.clear();
pinMode(interruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin), buttonPress, RISING);
}
void loop() {
unsigned long currentMillis = millis();
if((currentMillis - gotStartMillis > gotStartInterval) && gotStart) {
// i.e. hasnt gotEnd and gotStart is still true due to that.
mySerial.flush();
gotStart = false;
gotEnd = false;
gotStartMillis = currentMillis;
}
if(currentMillis - buttonMillis < buttonInterval) {
lcd.setBacklight(YELLOW);
} else {
lcd.setBacklight(LOW);
lcd.clear();
}
if(currentMillis - lastScreenMillis > screenInterval) {
if (screens > 0){
lcd.clear();
lcd.setCursor(0, 0);
for (int i = 0; i < ROWLEN; i++){
lcd.write(useBuf[(ROWLEN * 2 * currentScreen) + i]);
}
lcd.setCursor(0, 1);
for (int i = 0; i < ROWLEN; i++){
lcd.write(useBuf[(ROWLEN * 2 * currentScreen) + ROWLEN + i]);
}
if (++currentScreen > (screens - 1)){
currentScreen = 0;
}
lastScreenMillis = currentMillis;
}
}
if (flag == 1){ // button pressed
buttonMillis = millis();
buttonInterval = screenInterval * screens;// cycle all screens ;
currentScreen = 0;
lastScreenMillis = 0;
flag = 0;
}
while (mySerial.available()){
char c = mySerial.read();
if (c == 9){ // tab // got start char
gotStartMillis = millis();
gotStart = true;
} else if (c == 10){ // newline // got end char
if (gotStart){
// divisor * 2 because need 32 bytes to fill both rows of display
if (((byteCount - 1) % (ROWLEN * 2)) == 0){
screens = (byteCount - 1) / (ROWLEN * 2);
currentScreen = 0;
memcpy(&useBuf, readBuf, sizeof(readBuf));
}
}
gotStart = false;
gotEnd = false;
byteCount = 0;
} else {
readBuf[byteCount++] = c;
}
}
}
void buttonPress() {
flag = 1;
}
The PHP code in OpenWRT simply sends a string of data direct to /dev/ttyS1. (As long as its a multiple of 32 bytes)
If I ever decide to make a new version of this project I would do so with a newer version of the ALIX board (to get gigabit ethernet) and also make 2 PCB's to go in the case. One for the LCD and µC and another for 5 buttons. I'd also use hardware serial for communicating between OpenWRT and the board instead of SoftwareSerial (although SoftwareSerial does work OK)
(Page 4 of 4) | ||