Add files via upload

Added support for Auto/Standby (Key5 and 6)
This commit is contained in:
AK-Homberger
2019-08-03 13:27:40 +02:00
committed by GitHub
parent a83de91722
commit dac570bd41

View File

@@ -1,222 +1,238 @@
/*
This code is free software; you can redistribute it and/or /*
modify it under the terms of the GNU Lesser General Public This code is free software; you can redistribute it and/or
License as published by the Free Software Foundation; either modify it under the terms of the GNU Lesser General Public
version 2.1 of the License, or (at your option) any later version. License as published by the Free Software Foundation; either
This code is distributed in the hope that it will be useful, version 2.1 of the License, or (at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of This code is distributed in the hope that it will be useful,
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU but WITHOUT ANY WARRANTY; without even the implied warranty of
Lesser General Public License for more details. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
You should have received a copy of the GNU Lesser General Public Lesser General Public License for more details.
License along with this library; if not, write to the Free Software You should have received a copy of the GNU Lesser General Public
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA License along with this library; if not, write to the Free Software
*/ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// Version 1.0, 21.07.2019, AK-Homberger
// Version 1.1, 03.08.2019, AK-Homberger
#include <avr/pgmspace.h>
#include <RCSwitch.h> #include <avr/pgmspace.h>
#include <SPI.h> #include <RCSwitch.h>
#include <Wire.h> #include <SPI.h>
#include <Adafruit_GFX.h> #include <Wire.h>
#include <Adafruit_SSD1306.h> #include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET); #define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
RCSwitch mySwitch = RCSwitch();
#define Auto_Standby_Support 0 // Set this to 1 to support Standby and Auto for Key 5 and 6
const long unsigned int Key1 PROGMEM = 0000001; // Change values to individual values programmed to remote control
const long unsigned int Key2 PROGMEM = 0000002; RCSwitch mySwitch = RCSwitch();
const long unsigned int Key3 PROGMEM = 0000003;
const long unsigned int Key4 PROGMEM = 0000004; const long unsigned int Key_Minus_1 PROGMEM = 0000001; // Change values to individual values programmed to remote control
const long unsigned int Key_Plus_1 PROGMEM = 0000002;
// Seatalk datagrams const long unsigned int Key_Minus_10 PROGMEM = 0000003;
const long unsigned int Key_Plus_10 PROGMEM = 0000004;
const PROGMEM uint16_t ST_NMEA_BridgeID[] = { 0x190, 0x00, 0xA3 }; const long unsigned int Key_Auto PROGMEM = 0000005;
const long unsigned int Key_Standby PROGMEM = 0000006;
const PROGMEM uint16_t ST_Minus_1[] = { 0x186, 0x21, 0x05, 0xFA };
const PROGMEM uint16_t ST_Minus_10[] = { 0x186, 0x21, 0x06, 0xF9 }; // Seatalk datagrams
const PROGMEM uint16_t ST_Plus_1[] = { 0x186, 0x21, 0x07, 0xF8 };
const PROGMEM uint16_t ST_Plus_10[] = { 0x186, 0x21, 0x08, 0xF7 }; const PROGMEM uint16_t ST_NMEA_BridgeID[] = { 0x190, 0x00, 0xA3 };
const PROGMEM uint16_t ST_BeepOn[] = { 0x1A8, 0x53, 0x80, 0x00, 0x00, 0xD3 }; const PROGMEM uint16_t ST_Minus_1[] = { 0x186, 0x21, 0x05, 0xFA };
const PROGMEM uint16_t ST_BeepOff[] = { 0x1A8, 0x43, 0x80, 0x00, 0x00, 0xC3 }; const PROGMEM uint16_t ST_Minus_10[] = { 0x186, 0x21, 0x06, 0xF9 };
const PROGMEM uint16_t ST_Plus_1[] = { 0x186, 0x21, 0x07, 0xF8 };
boolean blink = true; const PROGMEM uint16_t ST_Plus_10[] = { 0x186, 0x21, 0x08, 0xF7 };
long unsigned int timer=0; const PROGMEM uint16_t ST_Auto[] = { 0x186, 0x21, 0x01, 0xFE };
long unsigned int timer1=0; const PROGMEM uint16_t ST_Standby[] = { 0x186, 0x21, 0x02, 0xFD };
long unsigned int timer2=0;
boolean sendDatagram(const uint16_t data[]) { const PROGMEM uint16_t ST_BeepOn[] = { 0x1A8, 0x53, 0x80, 0x00, 0x00, 0xD3 };
int i = 0; int j = 0; const PROGMEM uint16_t ST_BeepOff[] = { 0x1A8, 0x43, 0x80, 0x00, 0x00, 0xC3 };
boolean ok = true;
int bytes; boolean blink = true;
unsigned int inbyte; long unsigned int timer=0;
unsigned int outbyte; long unsigned int timer1=0;
long unsigned int timer2=0;
bytes = (pgm_read_byte_near(data + 1) & 0x0f) + 3; // Messege length is minimum 3, additional bytes in nibble 4
boolean sendDatagram(const uint16_t data[]) {
while (j < 5 ) { // CDMA/CD 5 tries int i = 0; int j = 0;
while (Serial1.available ()) { // Wait for silence on the bus boolean ok = true;
inbyte = (Serial1.read()); int bytes;
delay(3); unsigned int inbyte;
} unsigned int outbyte;
ok = true; bytes = (pgm_read_byte_near(data + 1) & 0x0f) + 3; // Messege length is minimum 3, additional bytes in nibble 4
for (i = 0; (i < bytes) & (ok == true); i++) { // Write and listen to detect collisions
outbyte = pgm_read_word_near(data + i); while (j < 5 ) { // CDMA/CD 5 tries
Serial1.write(outbyte); while (Serial1.available ()) { // Wait for silence on the bus
delay(3); inbyte = (Serial1.read());
delay(3);
if (Serial1.available ()) { }
inbyte = Serial1.read(); // Not what we sent, collision!
ok = true;
if (inbyte != outbyte) ok = false; for (i = 0; (i < bytes) & (ok == true); i++) { // Write and listen to detect collisions
} outbyte = pgm_read_word_near(data + i);
else ok = false; // Nothing received Serial1.write(outbyte);
} delay(3);
if ( ok )return ok; if (Serial1.available ()) {
inbyte = Serial1.read(); // Not what we sent, collision!
j++; // Collision detected
// Serial.println("CD"); if (inbyte != outbyte) ok = false;
// Display("Collision", 2); }
delay(random(2, 50)); // Random wait for next try else ok = false; // Nothing received
} }
Display("Send Error", 2);
return false; if ( ok )return ok;
}
j++; // Collision detected
// Serial.println("CD");
void Display(char *string, int size) // Display("Collision", 2);
{ delay(random(2, 50)); // Random wait for next try
display.clearDisplay(); }
display.setTextSize(size); Display("Send Error", 2);
display.setCursor(0, 0); return false;
display.println(string); }
display.display();
timer = 0;
} void Display(char *string, int size)
{
display.clearDisplay();
int checkWind(char * AWS) // Receice apparent wind speed from bus display.setTextSize(size);
{ display.setCursor(0, 0);
unsigned int xx; display.println(string);
unsigned int y; display.display();
unsigned int inbyte; timer = 0;
int wind = -1; }
if (Serial1.available ()) {
inbyte = Serial1.read(); int checkWind(char * AWS) // Receice apparent wind speed from bus
if (inbyte == 0x111) { // AWS Seatalk command - See reference from Thomas Knauf {
delay(3); unsigned int xx;
inbyte = Serial1.read(); unsigned int y;
if (inbyte == 0x01) { // AWS Setalk command unsigned int inbyte;
delay(3); int wind = -1;
xx = Serial1.read();
delay(3); if (Serial1.available ()) {
y = Serial1.read(); inbyte = Serial1.read();
wind = (xx & 0x7f) + (y / 10); // Wind speed if (inbyte == 0x111) { // AWS Seatalk command - See reference from Thomas Knauf
if (wind < 100) itoa (wind , AWS, 10); // Greater 100 must be a receive error delay(3);
} inbyte = Serial1.read();
} if (inbyte == 0x01) { // AWS Setalk command
} delay(3);
return wind; xx = Serial1.read();
} delay(3);
y = Serial1.read();
wind = (xx & 0x7f) + (y / 10); // Wind speed
void setup() if (wind < 100) itoa (wind , AWS, 10); // Greater 100 must be a receive error
{ }
Serial.begin( 9600 ); // Serial out put for function checks with PC }
Serial1.begin( 4800, SERIAL_9N1 ); // Set the Seatalk modus - 9 bit }
Serial1.setTimeout(5); return wind;
}
mySwitch.enableReceive(4); // RF Receiver on inerrupt 4 => that is pin 7 on Micro
pinMode(9, OUTPUT); // LED to show if keys are received void setup()
digitalWrite(9, HIGH); {
Serial.begin( 9600 ); // Serial out put for function checks with PC
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C (for the 128x64 from Conrad else 3D) Serial1.begin( 4800, SERIAL_9N1 ); // Set the Seatalk modus - 9 bit
display.setTextColor(WHITE); Serial1.setTimeout(5);
Display("Start", 4);
mySwitch.enableReceive(4); // RF Receiver on inerrupt 4 => that is pin 7 on Micro
sendDatagram(ST_NMEA_BridgeID); // Send NMEA Seatakl BridgeID to make Seatalk to Seatalk NG converter happy
} pinMode(9, OUTPUT); // LED to show if keys are received
digitalWrite(9, HIGH);
void loop() display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C (for the 128x64 from Conrad else 3D)
{ display.setTextColor(WHITE);
int i; Display("Start", 4);
char AWS[4] = "";
sendDatagram(ST_NMEA_BridgeID); // Send NMEA Seatakl BridgeID to make Seatalk to Seatalk NG converter happy
timer++;timer1++;timer2++; }
if (timer > 200000 ) {
Display("---", 7); // Show --- after about two seconds when no wind data is received void loop()
timer = 0; {
} int i;
char AWS[4] = "";
if (timer1 > 300000 ) {
sendDatagram(ST_BeepOff); // Additional Beep off after three seconds timer++;timer1++;timer2++;
timer1 = 0;
} if (timer > 200000 ) {
Display("---", 7); // Show --- after about two seconds when no wind data is received
timer = 0;
if (timer2 > 1000000 ) { }
sendDatagram(ST_NMEA_BridgeID); // Send NMEA Seatakl BridgeID every 10 seconds to make Seatalk to Seatalk NG converter happy
timer2 = 0; if (timer1 > 300000 ) {
} sendDatagram(ST_BeepOff); // Additional Beep off after three seconds
timer1 = 0;
}
if (checkWind(AWS) > -1) Display(AWS, 7);
if (mySwitch.available()) { if (timer2 > 1000000 ) {
long unsigned int value = mySwitch.getReceivedValue(); sendDatagram(ST_NMEA_BridgeID); // Send NMEA Seatakl BridgeID every 10 seconds to make Seatalk to Seatalk NG converter happy
timer2 = 0;
digitalWrite(9, blink); // LED on/off }
blink = !blink; // Toggle LED to show received key
mySwitch.resetAvailable(); if (checkWind(AWS) > -1) Display(AWS, 7);
if (value == Key1) { if (mySwitch.available()) {
Display("-1", 7); long unsigned int value = mySwitch.getReceivedValue();
sendDatagram(ST_Minus_1);
sendDatagram(ST_BeepOn); digitalWrite(9, blink); // LED on/off
delay(150); blink = !blink; // Toggle LED to show received key
sendDatagram(ST_BeepOff);
} mySwitch.resetAvailable();
if (value == Key2) { if (value == Key_Minus_1) {
Display("+1", 7); Display("-1", 7);
sendDatagram(ST_Plus_1); sendDatagram(ST_Minus_1);
sendDatagram(ST_BeepOn); sendDatagram(ST_BeepOn);
delay(150); delay(150);
sendDatagram(ST_BeepOff); sendDatagram(ST_BeepOff);
} }
if (value == Key3) { if (value == Key_Plus_1) {
Display("-10", 7); Display("+1", 7);
sendDatagram(ST_Minus_10); sendDatagram(ST_Plus_1);
sendDatagram(ST_BeepOn); sendDatagram(ST_BeepOn);
delay(150); delay(150);
sendDatagram(ST_BeepOff); sendDatagram(ST_BeepOff);
} }
if (value == Key4) { if (value == Key_Minus_10) {
Display("+10", 7); Display("-10", 7);
sendDatagram(ST_Plus_10); sendDatagram(ST_Minus_10);
sendDatagram(ST_BeepOn); sendDatagram(ST_BeepOn);
delay(150); delay(150);
sendDatagram(ST_BeepOff); sendDatagram(ST_BeepOff);
} }
i = 0; if ((value == Key_Auto) && (Auto_Standby_Support==1)) {
while (mySwitch.available() && i < 2) { Display("Auto", 7);
mySwitch.resetAvailable(); sendDatagram(ST_Auto);
delay (150); sendDatagram(ST_BeepOn);
i++; delay(150);
} sendDatagram(ST_BeepOff);
} }
}
if ((value == Key_Standby) && (Auto_Standby_Support==1)) {
Display("Standby", 7);
sendDatagram(ST_Standby);
sendDatagram(ST_BeepOn);
delay(150);
sendDatagram(ST_BeepOff);
}
i = 0;
while (mySwitch.available() && i < 2) {
mySwitch.resetAvailable();
delay (150);
i++;
}
}
}