/*
|
|
* ZMHW Project: Map
|
|
*
|
|
* A device to give you a visual representation of what Monitors
|
|
* are active in your camera network.
|
|
*
|
|
* SteakElectronics, December 2018
|
|
* Rare steak, well done electronics.
|
|
*
|
|
* Based on: telnet client
|
|
*
|
|
* Requires: UIPEthernet library
|
|
*
|
|
* Nice to haves in future:
|
|
* PWM dimming, after alarms are off, so you know what was recently on.
|
|
* Blinking on active alarms, instead of solid light, maybe.
|
|
* Faster direct port access than digitalwrite. There are some libraries
|
|
* but I don't know if they support the Mega. Instead, I'm going to rebuild the board
|
|
* with a led matrix, and then use pwm pins, and I will deal with it then.
|
|
* EDIT: instead maybre I'll use two 0402 resistors, and make a voltage divider, to allow for
|
|
* dimmer led, with hardware instead of software.
|
|
*
|
|
* Troubleshooting Programming: When connecting, it can take 30-60 seconds
|
|
* to speed this up, run the test suite telnet connect and it should connect
|
|
* immediately after. The idea is that, it seems to connect as soon as a packet is
|
|
* sent from zmtrigger. So send a test telnet packet, then it will connect after.
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
Telnet client
|
|
|
|
This sketch connects to a a telnet server (http://www.google.com)
|
|
using an Arduino Wiznet Ethernet shield. You'll need a telnet server
|
|
to test this with.
|
|
Processing's ChatServer example (part of the network library) works well,
|
|
running on port 10002. It can be found as part of the examples
|
|
in the Processing application, available at
|
|
http://processing.org/
|
|
|
|
Circuit:
|
|
* Ethernet shield attached to pins 10, 11, 12, 13
|
|
|
|
created 14 Sep 2010
|
|
modified 9 Apr 2012
|
|
by Tom Igoe
|
|
|
|
*/
|
|
|
|
#include <SPI.h>
|
|
#include <UIPEthernet.h>
|
|
|
|
|
|
#define DEBUGMODE 0 // 1:on 0:off
|
|
#define DEBUGMODE2 0
|
|
|
|
// Enter a MAC address and IP address for your controller below.
|
|
// The IP address will be dependent on your local network:
|
|
byte mac[] = {
|
|
0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x41
|
|
};
|
|
IPAddress ip(192, 168, 78, 60);
|
|
|
|
// Enter the IP address of the server you're connecting to:
|
|
IPAddress server(192, 168, 78, 123);
|
|
// Port of ZMTrigger
|
|
#define ZMTRIGGERPORT 6802
|
|
|
|
// Initialize the Ethernet client library
|
|
// with the IP address and port of the server
|
|
// that you want to connect to (port 23 is default for telnet;
|
|
// if you're using Processing's ChatServer, use port 10002):
|
|
EthernetClient client;
|
|
|
|
//Make a server
|
|
//Not currently working.
|
|
#define LISTENPORT 80 // (port 80 is default for HTTP)
|
|
EthernetServer server2 = EthernetServer(LISTENPORT);
|
|
|
|
//Globals
|
|
|
|
char* zmtrigarray[50] = {0};
|
|
uint8_t x = 0;
|
|
uint8_t y = 0;
|
|
uint8_t Mon1 = 0;
|
|
uint8_t Mon2 = 0;
|
|
uint8_t MonFIN = 0;
|
|
|
|
char mask = 0x0F; //get last nibble
|
|
uint8_t Mon1Nib = Mon1 & mask;
|
|
uint8_t Mon2Nib = Mon2 & mask;
|
|
|
|
char on = 0b01101110; //n (ascii)
|
|
char off = 0b01100110; //f (ascii)
|
|
|
|
|
|
|
|
int value = 0;
|
|
int ADD = 3; //We start at digital pin 4. so add 3 to everything.
|
|
//e.g. Monitor 3 is digital pin 6.
|
|
|
|
uint8_t NEEDCOLOUR = 0;
|
|
|
|
|
|
|
|
|
|
// Simple PWM
|
|
|
|
//if this is 1, bypass interrupt / softpwm, else do softpwm
|
|
uint8_t BypassSoftPWM[50] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
|
|
|
int ledState[50] = {0}; // ledState used to set the LED
|
|
|
|
#define LEDTIME 10000 // 2000 comes out to about 8 seconds
|
|
uint16_t onInterval[50] = {LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME,LEDTIME}; // How long to display dimmed led
|
|
|
|
uint8_t FLIP[50] = {0};
|
|
uint8_t PWMCounter = 0;
|
|
uint8_t OffOverride[50] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
|
uint8_t OffCtr[50] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
|
|
|
|
|
|
|
|
|
|
|
//during interrupt, we SoftPWM any LEDs that are ready to be done so
|
|
ISR(TIMER3_COMPA_vect) {
|
|
|
|
for(x=1;x<51;x++){
|
|
if(BypassSoftPWM[x] == 1){
|
|
|
|
//Serial.print("Bypass activated for monitor: ");
|
|
//Serial.println(x);
|
|
|
|
///FLIP[x] = 0;
|
|
if(onInterval[x] == LEDTIME){
|
|
//note: These serial prints, cause delays that mess up softpwm
|
|
if(DEBUGMODE){
|
|
Serial.print(F("Turning on SoftPWM for Monitor: "));
|
|
Serial.println(x);
|
|
}
|
|
}
|
|
//turn off
|
|
//might be better to do equals for all cases
|
|
if(PWMCounter < 7){
|
|
digitalWrite(x + ADD, 0);
|
|
}
|
|
|
|
//turn on
|
|
//must be after turn off, otherwise, if before, it will
|
|
//immediately be turned off
|
|
if(PWMCounter > 7){
|
|
digitalWrite(x + ADD, 1);
|
|
PWMCounter = 0;
|
|
//Serial.print(F("Dim Led #: "));
|
|
//Serial.println(x);
|
|
}
|
|
|
|
|
|
|
|
PWMCounter = PWMCounter + 1;
|
|
//Serial.print("PWM Count is: ");
|
|
//Serial.println(PWMCounter);
|
|
|
|
//This is only for debug. Slows delay down.
|
|
//Serial.print("oninterval is:");
|
|
//Serial.println(onInterval[x]);
|
|
|
|
onInterval[x] = onInterval[x] - 1;
|
|
if (onInterval[x] == 0){
|
|
BypassSoftPWM[x] = 0;
|
|
//note: These serial prints, cause delays that mess up softpwm
|
|
if(DEBUGMODE){
|
|
Serial.print("Turning off softPWM on Monitor: ");
|
|
Serial.println(x);
|
|
}
|
|
digitalWrite(x + ADD, 0);
|
|
onInterval[x] = LEDTIME;
|
|
//no need for softpwm override
|
|
OffOverride[x] = 0;
|
|
OffCtr[x] = 0;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
//Check if any monitors that didn't get the shutdown message
|
|
ISR(TIMER4_COMPA_vect) {
|
|
|
|
for(x=1;x<51;x++){
|
|
if (OffOverride[x] == 1){
|
|
OffCtr[x]++;
|
|
|
|
if (OffCtr[x] == 50){
|
|
OffOverride[x] = 0;
|
|
OffCtr[x] = 0;
|
|
digitalWrite(x + ADD, 0);
|
|
Serial.print(F("Turning off due to override. Monitor #: "));
|
|
Serial.println(x);
|
|
sendPixel(0,10,10);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void setup() {
|
|
|
|
|
|
// in case we are restarting the setup loop because we didn't connect,
|
|
// we don't want timer to interfere
|
|
TCCR3A = 0;
|
|
TCCR3B = 0;
|
|
TCNT3 = 0;
|
|
|
|
//RGB LED
|
|
/*define Pin 2/PE4 as output*/
|
|
/*Libraries included w/arduino IDE*/
|
|
DDRE = 0b00010000;
|
|
|
|
// Open serial communications and wait for port to open:
|
|
Serial.begin(9600);
|
|
while (!Serial) {
|
|
; // wait for serial port to connect. Needed for native USB port only
|
|
}
|
|
sendPixel(10,0,0);
|
|
delay(500);
|
|
sendPixel(0,10,0);
|
|
delay(500);
|
|
sendPixel(0,0,10);
|
|
|
|
|
|
Serial.println("ZMHW Project: Map");
|
|
//Using pins 4 to 49
|
|
for (x=4;x<49;x++){
|
|
pinMode(x, OUTPUT);
|
|
digitalWrite(x, LOW);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// start the Ethernet connection:
|
|
Ethernet.begin(mac, ip);
|
|
// give the Ethernet shield a second to initialize:
|
|
delay(1000);
|
|
Serial.println("connecting...");
|
|
|
|
|
|
// if you get a connection, report back via serial:
|
|
if (client.connect(server, ZMTRIGGERPORT)) {
|
|
Serial.println("connected");
|
|
|
|
//Test all LEDs
|
|
for (x=4;x<49;x++){
|
|
digitalWrite(x, HIGH);
|
|
delay(50);
|
|
digitalWrite(x, LOW);
|
|
|
|
}
|
|
} else {
|
|
// if you didn't get a connection to the server:
|
|
Serial.println("connection failed");
|
|
|
|
|
|
for(int err = 0; err<3;err++){
|
|
sendPixel(0,10,0);
|
|
delay(100);
|
|
sendPixel(0,0,0);
|
|
delay(100);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// AVR Timer CTC Interrupts Calculator
|
|
// v. 8
|
|
// http://www.arduinoslovakia.eu/application/timer-calculator
|
|
// Microcontroller: ATmega2560
|
|
// Created: 2019-02-02T06:08:33.492Z
|
|
|
|
//dimming is buggy. doesn't quite work.
|
|
//problem is viewed with a scope, the timers seem to fault
|
|
//only pwming on one led occasionally
|
|
//setupTimer3();
|
|
sendPixel(0,10,10);
|
|
setupTimer4();
|
|
|
|
|
|
|
|
}
|
|
|
|
void loop() {
|
|
|
|
// if there are incoming bytes available
|
|
// from the server, read them and print them:
|
|
|
|
//original
|
|
/*if (client.available()) {
|
|
char c = client.read();
|
|
Serial.print(c);
|
|
}*/
|
|
//if (client.available()) {
|
|
// char* zmtrigarray = client.read();
|
|
// Serial.print(zmtrigarray);
|
|
//}
|
|
if (client.available()){
|
|
|
|
for(int x=0;x<40;x++){
|
|
//there are two UIPClient.ccp client.read functions. this is the 2nd
|
|
zmtrigarray[x] = client.read();
|
|
if(zmtrigarray[x] == 0b00001010){ //if line break is found in telnet
|
|
y = x;
|
|
goto PRINT;
|
|
}
|
|
}
|
|
PRINT:
|
|
|
|
uint8_t WhereInTheWorldIsThe1stLine = 0;
|
|
uint8_t WhereInTheWorldIsThe2ndLine = 0;
|
|
|
|
//Serial.println("Finished reading client");
|
|
if(DEBUGMODE){
|
|
for(int x=0;x<y;x++){
|
|
Serial.print((char)zmtrigarray[x]);
|
|
}
|
|
Serial.println(F(""));
|
|
//debugging
|
|
for(int x=0;x<y;x++){
|
|
Serial.print(F("x is: "));
|
|
Serial.print(x);
|
|
Serial.print(F(" val is: "));
|
|
Serial.print((char)zmtrigarray[x]);
|
|
Serial.print(F(" bytecode is: "));
|
|
Serial.print((char)zmtrigarray[x], DEC); //print int rep of byte
|
|
Serial.print(F(" binary is: "));
|
|
Serial.print((char)zmtrigarray[x], BIN); //print int rep of byte
|
|
//line break is 10 in telnet
|
|
Serial.println(F(""));
|
|
}
|
|
Serial.println(F(""));
|
|
}//end DEBUG
|
|
|
|
//Find out monitor we have
|
|
//
|
|
if(zmtrigarray[1] == 0b01111100) { //looking for vertical dash, in spot 2 (1 of array)
|
|
Mon1 = zmtrigarray[0];
|
|
Mon1Nib = Mon1 & mask;
|
|
MonFIN = Mon1Nib;
|
|
WhereInTheWorldIsThe1stLine = 1;
|
|
if(DEBUGMODE){
|
|
Serial.print(F("Mon1 is: "));
|
|
Serial.println(Mon1Nib, BIN);
|
|
Serial.print(F("Monitor number is: "));
|
|
Serial.println(MonFIN, DEC);
|
|
Serial.println(MonFIN, BIN);
|
|
}
|
|
}
|
|
|
|
if(zmtrigarray[1] != 0b01111100){ //looking for vertical dash, for two digit number
|
|
Mon1 = zmtrigarray[0];
|
|
Mon1Nib = Mon1 & mask; //convert from ascii to decimal
|
|
WhereInTheWorldIsThe1stLine = 2;
|
|
if(DEBUGMODE){
|
|
Serial.print(F("Mon1 is: "));
|
|
Serial.println(Mon1Nib, BIN);
|
|
}
|
|
Mon2 = zmtrigarray[1];
|
|
Mon2Nib = Mon2 & mask; //convert from ascii to decimal
|
|
if(DEBUGMODE){
|
|
Serial.print(F("Mon2 is: "));
|
|
Serial.println(Mon2Nib, BIN);
|
|
}
|
|
|
|
MonFIN = Mon1Nib & Mon2Nib;
|
|
char MonBUF[2];
|
|
sprintf(MonBUF,"%d%d", Mon1Nib,Mon2Nib);
|
|
MonFIN = atoi(MonBUF); //To convert from Ascii to dec, we take the lower 4 bits,
|
|
//convert to a string, then convert to int.
|
|
|
|
if(DEBUGMODE){
|
|
Serial.print(F("Monitor number is: "));
|
|
Serial.println(MonFIN, DEC);
|
|
Serial.println(MonFIN, BIN);
|
|
}
|
|
}//end vertical dash search (when in spot 3)
|
|
|
|
//Looking for an N or an F (for ON or OFF)
|
|
//possible values: On, Off
|
|
char OnOffSwitch = 0;
|
|
OnOffSwitch = zmtrigarray[WhereInTheWorldIsThe1stLine+2];
|
|
if(DEBUGMODE){
|
|
Serial.print(F("On/Off Switch is: "));
|
|
Serial.println(OnOffSwitch);
|
|
}
|
|
|
|
|
|
if(OnOffSwitch == on){
|
|
|
|
|
|
//Now, we block SoftPWM, in case LED was dimmed
|
|
BypassSoftPWM[MonFIN] = 0;
|
|
//Reset this, in case LED was dimmed
|
|
onInterval[MonFIN] = LEDTIME;
|
|
|
|
OffOverride[MonFIN] = 0;
|
|
OffCtr[MonFIN] = 0;
|
|
|
|
if (DEBUGMODE){
|
|
Serial.print("Bypass soft pwm value is:");
|
|
Serial.println(BypassSoftPWM[MonFIN], DEC);
|
|
|
|
Serial.print(F("On Detected for Monitor: "));
|
|
Serial.println(MonFIN, DEC);
|
|
}
|
|
value = (MonFIN + ADD);
|
|
|
|
//minus 1 as array starts at 0
|
|
//BypassSoftPWM[MonFIN - 1] = 1;
|
|
//Serial.print("Bypass soft pwm value is:");
|
|
//Serial.println(BypassSoftPWM[MonFIN - 1], DEC);
|
|
LEDAlight(value, 0xFF);
|
|
|
|
//Visual notification alarm has been off lately
|
|
sendPixel(20,20,20);
|
|
|
|
|
|
}
|
|
else if(OnOffSwitch == off){
|
|
|
|
if (DEBUGMODE){
|
|
Serial.print(F("Off Detected for Monitor: "));
|
|
Serial.println(MonFIN, DEC);
|
|
}
|
|
value = (MonFIN + ADD);
|
|
|
|
//Start watchdog timer to shutdown leds that dont stop
|
|
OffOverride[MonFIN] = 1;
|
|
|
|
|
|
//Now, we allow SoftPWM, as LED was just turned off.
|
|
//minus 1 as array starts at 0
|
|
BypassSoftPWM[MonFIN] = 1;
|
|
if (DEBUGMODE){
|
|
Serial.print(F("Bypass soft pwm value is:"));
|
|
Serial.println(BypassSoftPWM[MonFIN], DEC);
|
|
}
|
|
|
|
LEDAlight(value, 0x00); //turn led off
|
|
|
|
|
|
//SoftPWM_LED_dim(value, Interval, MonFIN);
|
|
|
|
}
|
|
else if (OnOffSwitch != on && OnOffSwitch != off){
|
|
Serial.println(F("Incorrect On/Off Value"));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
//WebServer(); //todo
|
|
|
|
|
|
// as long as there are bytes in the serial queue,
|
|
// read them and send them out the socket if it's open:
|
|
while (Serial.available() > 0) {
|
|
char inChar = Serial.read();
|
|
if (client.connected()) {
|
|
client.print(inChar);
|
|
|
|
}
|
|
}
|
|
|
|
// if the server's disconnected, stop the client:
|
|
if (!client.connected()) {
|
|
Serial.println();
|
|
Serial.println("disconnecting.");
|
|
client.stop();
|
|
// do nothing:
|
|
//while (true);
|
|
|
|
//GREEN to RED Error
|
|
for(int err = 0; err<9;err++){
|
|
sendPixel(10,0,0);
|
|
delay(100);
|
|
sendPixel(0,10,0);
|
|
delay(100);
|
|
}
|
|
|
|
//start over
|
|
setup();
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
uint8_t LEDAlight (int Monitor, int Switch){
|
|
//Enable or Disable GPIO based on Monitor
|
|
//and Switch value
|
|
|
|
digitalWrite(Monitor, Switch);
|
|
if (DEBUGMODE){
|
|
Serial.print(F("LED # has been switched: "));
|
|
Serial.print(Monitor);
|
|
Serial.print(F(" "));
|
|
}
|
|
if(Switch == 0xFF){
|
|
if (DEBUGMODE){
|
|
Serial.println(F(" On"));
|
|
}
|
|
}
|
|
else{
|
|
if (DEBUGMODE){
|
|
Serial.println(F(" Off"));
|
|
}
|
|
}
|
|
}
|
|
|
|
//This will fade out the LED
|
|
uint8_t SoftPWM_LED_dim (uint8_t Monbitbangpwm, uint16_t *ptr, uint8_t ptrarraynum){
|
|
|
|
|
|
//arrays start at 0
|
|
ptrarraynum = ptrarraynum - 1;
|
|
|
|
|
|
if(DEBUGMODE){
|
|
//check I did my pointers right...
|
|
Serial.println(F("SoftPWM: ...."));
|
|
Serial.print(F("Mega Pin is:"));
|
|
Serial.println(Monbitbangpwm);
|
|
int TempMon = Monbitbangpwm - ADD;
|
|
Serial.print(F("Monitor is:"));
|
|
Serial.println(TempMon);
|
|
Serial.print(F("Interval from within softPWM is:"));
|
|
//It's easier to understand, if you call it pass reference to pointer, not pass by reference to pointer.
|
|
//aka pointer can pass value (the value of the data, but not the original data), or pass reference (a reference to the original data)
|
|
//that little "by" word, makes things much more incomprehensible.
|
|
for( int x = 0 ; x <= 50 ; x++ ){
|
|
Serial.println( ptr[x], HEX );
|
|
//ptr[x] = ptr[x] + 1; //looks like by default arrays pass a reference to array
|
|
//no need for ptr magic
|
|
// https://forum.arduino.cc/index.php?topic=42546.0
|
|
}
|
|
}
|
|
if(DEBUGMODE)
|
|
{
|
|
Serial.println( ptr[ptrarraynum], DEC );
|
|
//Now start LED dimming timer
|
|
//ptr[ptrarraynum] = 200;
|
|
//Serial.println( "now 200: ");
|
|
//Serial.println( ptr[ptrarraynum], DEC );
|
|
}
|
|
//start LED dimming timer
|
|
ptr[ptrarraynum] = 2000;
|
|
Serial.println( ptr[ptrarraynum], DEC );
|
|
Serial.println( ptrarraynum, DEC );
|
|
Serial.println( "Is now at what was above the num.");
|
|
|
|
}
|
|
|
|
|
|
//interrupt 15hz
|
|
//from https://www.arduinoslovakia.eu/application/timer-calculator
|
|
//would be nice if it was downloadable...
|
|
|
|
void setupTimer3() {
|
|
noInterrupts();
|
|
// Clear registers
|
|
TCCR3A = 0;
|
|
TCCR3B = 0;
|
|
TCNT3 = 0;
|
|
|
|
/*
|
|
// 15.00060002400096 Hz (16000000/((16665+1)*64))
|
|
OCR3A = 16665;
|
|
// CTC
|
|
TCCR3B |= (1 << WGM32);
|
|
// Prescaler 64
|
|
TCCR3B |= (1 << CS31) | (1 << CS30);
|
|
// Output Compare Match A Interrupt Enable
|
|
TIMSK3 |= (1 << OCIE3A);
|
|
*/
|
|
|
|
/*
|
|
// 60.00060000600006 Hz (16000000/((33332+1)*8))
|
|
OCR3A = 33332;
|
|
// CTC
|
|
TCCR3B |= (1 << WGM32);
|
|
// Prescaler 8
|
|
TCCR3B |= (1 << CS31);
|
|
// Output Compare Match A Interrupt Enable
|
|
TIMSK3 |= (1 << OCIE3A);
|
|
*/
|
|
|
|
// 240.00960038401536 Hz (16000000/((8332+1)*8))
|
|
OCR3A = 8332;
|
|
// CTC
|
|
TCCR3B |= (1 << WGM32);
|
|
// Prescaler 8
|
|
TCCR3B |= (1 << CS31);
|
|
// Output Compare Match A Interrupt Enable
|
|
TIMSK3 |= (1 << OCIE3A);
|
|
|
|
interrupts();
|
|
}
|
|
|
|
//using this to count 1hz, in case any buggy reports from telnet
|
|
//sometimes i see a lot of monitors light up, then immediately turn off
|
|
//on telnet, so accounting for that.
|
|
void setupTimer4() {
|
|
noInterrupts();
|
|
// Clear registers
|
|
TCCR4A = 0;
|
|
TCCR4B = 0;
|
|
TCNT4 = 0;
|
|
|
|
// 1 Hz (16000000/((15624+1)*1024))
|
|
OCR4A = 15624;
|
|
// CTC
|
|
TCCR4B |= (1 << WGM42);
|
|
// Prescaler 1024
|
|
TCCR4B |= (1 << CS42) | (1 << CS40);
|
|
// Output Compare Match A Interrupt Enable
|
|
TIMSK4 |= (1 << OCIE4A);
|
|
interrupts();
|
|
}
|
|
|
|
|
|
|
|
void WebServer (void){
|
|
/********************SERVER STATUS PAGE*********************/
|
|
/*
|
|
* With this, you can logon to the Sensor from your LAN to find
|
|
* out just what device this IP address is, in case you happen to
|
|
* forget.
|
|
*/
|
|
|
|
//Serial.println("In server");
|
|
//Server Status Page
|
|
// listen for incoming clients
|
|
EthernetClient client3 = server2.available();
|
|
if (client3) {
|
|
Serial.println(F("web visitor"));
|
|
// an http request ends with a blank line
|
|
boolean currentLineIsBlank = true;
|
|
while (client3.connected()) {
|
|
if (client3.available()) {
|
|
char c = client3.read();
|
|
Serial.write(c);
|
|
// if you've gotten to the end of the line (received a newline
|
|
// character) and the line is blank, the http request has ended,
|
|
// so you can send a reply
|
|
if (c == '\n' && currentLineIsBlank) {
|
|
// send a standard http response header
|
|
client3.println("HTTP/1.1 200 OK");
|
|
client3.println("Content-Type: text/html");
|
|
client3.println();
|
|
client3.println("<!DOCTYPE HTML>");
|
|
client3.println("<html><pre>");
|
|
client3.println("<b>Steak Electronics</b>");
|
|
client3.println("\"Steak it One Steak at a time.\"");
|
|
client3.println("");
|
|
//client.println("<b>IP Address:</b>");
|
|
//client.println(Ethernet.localIP());
|
|
//client.print("Sensor Location:");
|
|
//client.println(LOCATIONOFSENSOR);
|
|
client3.print("Type:");
|
|
client3.println("ZMHW Map");
|
|
client3.print("Last Activity was Monitor: ");
|
|
client3.println(MonFIN);
|
|
client3.println("</pre></html>");
|
|
break;
|
|
}
|
|
if (c == '\n') {
|
|
// you're starting a new line
|
|
currentLineIsBlank = true;
|
|
} else if (c != '\r') {
|
|
// you've gotten a character on the current line
|
|
currentLineIsBlank = false;
|
|
}
|
|
}
|
|
}
|
|
// give the web browser time to receive the data
|
|
delay(1);
|
|
// close the connection:
|
|
client.stop();
|
|
Serial.println(F("web visitor disconnected"));
|
|
}
|
|
}
|
|
|
|
void PixZero (void){
|
|
PORTE = 0b00010000;
|
|
//_delay_us(0.25);
|
|
PORTE = 0x00;
|
|
//_delay_us(0.25);
|
|
}
|
|
void PixOne (void){
|
|
PORTE = 0b00010000;
|
|
//_delay_us(0.55);
|
|
_delay_us(0.55);
|
|
PORTE = 0x00;
|
|
}
|
|
void PixBit (bool res){
|
|
|
|
if (res == false){
|
|
PixZero();
|
|
}
|
|
if (res == true){
|
|
PixOne();
|
|
}
|
|
|
|
}
|
|
|
|
void PixByte (char input){
|
|
uint8_t changer = 0;
|
|
|
|
//WS2812 reads bits as left is lowest (high in first), so go backwards
|
|
for(changer=8;changer>0;changer--){
|
|
PixBit(bitRead(input, changer));
|
|
//input <<= 1; //Atmega didn't like this, so instead, using changer
|
|
//instead of shifting input
|
|
}
|
|
}
|
|
|
|
void sendPixel(uint8_t g, uint8_t r, uint8_t b){
|
|
|
|
/*ws2812, reads bits left side as lowest*/
|
|
/*PixByte(0b10100000); //This is dim green
|
|
PixByte(0b00000000);
|
|
PixByte(0b00000000);
|
|
PixByte(0b00000000); //no white on my LED*/
|
|
|
|
|
|
PixByte(g);
|
|
PixByte(r);
|
|
PixByte(b);
|
|
//PixByte(w);
|
|
PORTE = 0x00;
|
|
|
|
|
|
}
|
|
void PulseRGB_g (uint8_t max, uint8_t r, uint8_t b){
|
|
int rgbfunc = 0;
|
|
for (rgbfunc = 0; rgbfunc < max; rgbfunc++){
|
|
sendPixel(rgbfunc,r,b);
|
|
delay(22);
|
|
}
|
|
for (rgbfunc = max; rgbfunc > 0; rgbfunc--){
|
|
sendPixel(rgbfunc,r,b);
|
|
delay(22);
|
|
}
|
|
}
|
|
void PulseRGB_r (uint8_t max, uint8_t g, uint8_t b){
|
|
int rgbfunc = 0;
|
|
for (rgbfunc = 0; rgbfunc < max; rgbfunc++){
|
|
sendPixel(g,rgbfunc, b);
|
|
delay(22);
|
|
}
|
|
for (rgbfunc = max; rgbfunc > 0; rgbfunc--){
|
|
sendPixel(g,rgbfunc, b);
|
|
delay(22);
|
|
}
|
|
}
|
|
void PulseRGB_b (uint8_t max, uint8_t g, uint8_t r){
|
|
int rgbfunc = 0;
|
|
for (rgbfunc = 0; rgbfunc < max; rgbfunc++){
|
|
sendPixel(g,r,rgbfunc);
|
|
delay(22);
|
|
}
|
|
for (rgbfunc = max; rgbfunc > 0; rgbfunc--){
|
|
sendPixel(g,r,rgbfunc);
|
|
delay(22);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|