Merge branch 'review' into testing
This commit is contained in:
commit
68da22384a
|
@ -0,0 +1 @@
|
|||
.vscode/
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
//Copyright (C) 2010-2014 Henk Jegers
|
||||
//Copyright (C) 2019 giuliof (GOLEM)
|
||||
//This program is free software: you can redistribute it and/or modify
|
||||
//it under the terms of the GNU General Public License as published by
|
||||
//the Free Software Foundation, either version 3 of the License, or
|
||||
|
@ -18,34 +18,9 @@
|
|||
// version MEGA01_2 Added end number information. Needs Archeryclock2401 or newer. (older archeryclock versions don't sent the end number information to arduine)
|
||||
// version MEGA02_1 Changes because of a change in protocoll for AC 241 (nr of archers and E and F shooters) and added functionality: emergency stop, add archers E and F. Changes for signal robustness. (0 (0000) is sent as 12 (1100) to prevent decoding issues when 3 times 0 is sent (000000000000)
|
||||
|
||||
String inputString;
|
||||
int serialvalue;
|
||||
int statevalue; //received data for state details.
|
||||
int trafficvalue; //received data for traffic lights, and ABCD lights
|
||||
int leftcountvalue; //received data for left countdown.
|
||||
int rightcountvalue; //received data for rightcountdown.
|
||||
int abcdvalue; //received data for abcd details
|
||||
int endnrvalue; //received data for end nr
|
||||
int buttonvalue;
|
||||
int remember1;
|
||||
int loop1;
|
||||
int blinkk;
|
||||
int blinkkk;
|
||||
int blinkl;
|
||||
int blinkr;
|
||||
int rightdigit; //value of left digit (0..10 (10 means dashes))
|
||||
int middigit; //value of middle digit (0..10 (10 means dashes))
|
||||
int leftdigit; //value of light digit (0..10 (10 means dashes))
|
||||
|
||||
int lefend; //value of left digit to indicate end nr (0..9 or 15 (15 means P to indicate practise end))
|
||||
int midend; //value of middle digit to indicate end nr (0..9)
|
||||
int rigend; //value of middle digit to indicate end nr (0..9)
|
||||
int comend; //value of combined left and middle digit. In case of practise end the P from the left digit should be projected. else the middle digit (0..9 or 15 (15 means P to indicate practise end))
|
||||
|
||||
#define CHAR_P 15
|
||||
#define CHAR_DASH 10
|
||||
const uint8_t segment[16] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x40, 0x00, 0x3f, 0x00, 0x00, 0x73}; //0,1,2,3,4,5,6,7,8,9,-, , , , ,P
|
||||
#include "utils.h"
|
||||
|
||||
// Commands data structures
|
||||
enum PanelSide_t
|
||||
{
|
||||
LEFT = 0,
|
||||
|
@ -60,7 +35,7 @@ struct cfg_t
|
|||
{
|
||||
PanelSide_t PanelSide : 1;
|
||||
BuzzerStatus_t BuzzerStatus : 1;
|
||||
uint8_t abcd : 4; // unclear meaning
|
||||
uint8_t abcd : 3; // unclear meaning
|
||||
uint8_t competition : 3; // unclear meaning
|
||||
uint8_t GroupsNumber : 6;
|
||||
uint8_t : 0;
|
||||
|
@ -79,7 +54,7 @@ struct trafficvalue_t
|
|||
struct statevalue_t
|
||||
{
|
||||
uint8_t cmd : 4;
|
||||
uint8_t abcd : 4; // unclear meaning
|
||||
uint8_t abcd : 3; // unclear meaning
|
||||
uint8_t competition : 3; // unclear meaning
|
||||
uint8_t : 3;
|
||||
uint8_t GroupsNumber : 6;
|
||||
|
@ -104,31 +79,56 @@ union ReceivedCommand_t {
|
|||
digitsvalue_t d;
|
||||
} ReceivedCommand;
|
||||
|
||||
#define DOTS_bm _BV(7)
|
||||
|
||||
#define ABCD_PORT A
|
||||
#define LEFTDIGIT_PORT K
|
||||
#define MIDDIGIT_PORT L
|
||||
#define RIGHTDIGIT_PORT C
|
||||
#define TRAFLIGHT_PORT F
|
||||
|
||||
#define HORNP_PIN 7
|
||||
#define REDP_PIN 6
|
||||
#define ORANGEP_PIN 5
|
||||
#define GREENP_PIN 4
|
||||
|
||||
#define notA_PIN 78
|
||||
#define notB_PIN 77
|
||||
#define notC_PIN 76
|
||||
#define notD_PIN 75
|
||||
#define A_PIN 74
|
||||
#define B_PIN 73
|
||||
#define C_PIN 72
|
||||
#define D_PIN 71
|
||||
|
||||
#define LR_PIN 9
|
||||
#define MUTE_PIN 8
|
||||
|
||||
// "translation" for seven segment
|
||||
#define CHAR_P 15
|
||||
#define CHAR_DASH 10
|
||||
const uint8_t segment[16] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x40, 0x00, 0x3f, 0x00, 0x00, 0x73}; //0,1,2,3,4,5,6,7,8,9,-, , , , ,P
|
||||
|
||||
void setup()
|
||||
{
|
||||
pinMode(LR_PIN, INPUT_PULLUP);
|
||||
pinMode(MUTE_PIN, INPUT_PULLUP);
|
||||
|
||||
// All following port banks are outputs for transistors array
|
||||
DDRF = 0xFF; // Analog 0~7
|
||||
DDRK = 0xFF; // Analog 8~15
|
||||
DDRL = 0xFF;
|
||||
DDRA = 0xFF;
|
||||
DDRC = 0xFF;
|
||||
CATDDR(ABCD_PORT) = 0xFF;
|
||||
CATDDR(LEFTDIGIT_PORT) = 0xFF;
|
||||
CATDDR(MIDDIGIT_PORT) = 0xFF;
|
||||
CATDDR(RIGHTDIGIT_PORT) = 0xFF;
|
||||
CATDDR(TRAFLIGHT_PORT) = 0xFF;
|
||||
|
||||
pinMode(REDP_PIN, OUTPUT);
|
||||
pinMode(ORANGEP_PIN, OUTPUT);
|
||||
pinMode(GREENP_PIN, OUTPUT);
|
||||
pinMode(HORNP_PIN, OUTPUT);
|
||||
|
||||
// Load system configuration
|
||||
cfg.BuzzerStatus = digitalRead(A4) ? BUZZER_ON : BUZZER_OFF;
|
||||
cfg.PanelSide = digitalRead(A5) ? RIGHT : LEFT;
|
||||
|
||||
remember1 = 0;
|
||||
loop1 = 0;
|
||||
blinkk = 0;
|
||||
blinkkk = 0;
|
||||
blinkl = 0;
|
||||
blinkr = 0;
|
||||
|
||||
rightcountvalue = 0xAAA0;
|
||||
leftcountvalue = 0xAAA0;
|
||||
serialvalue = 0x0000;
|
||||
|
||||
// Communication w/PC for debug or other puroposes
|
||||
Serial.begin(9600);
|
||||
Serial.println("Arduino Serial Link");
|
||||
|
@ -140,6 +140,7 @@ void setup()
|
|||
|
||||
void loop()
|
||||
{
|
||||
// A command is received
|
||||
if (Serial1.available())
|
||||
{
|
||||
/* ** Buffer to store received char **
|
||||
|
@ -155,56 +156,102 @@ void loop()
|
|||
ReceivedCommand.raw = inputString.toInt();
|
||||
inputString = "";
|
||||
|
||||
// Decode command
|
||||
// Now decode command and apply to the panel
|
||||
// Refer to documentation for command structure
|
||||
|
||||
//16 bits data received.
|
||||
//first bit is telling if the data is about traffic lights and ABCD lights (true). or about the digits of the countdown (false).
|
||||
//second bit is telling:
|
||||
// -in case of digits (first bit is 0)if the digits are from the right side countdown (true) or left side countdown (false).
|
||||
// -in case of trafic/ABCD lights: not implemented jet. Proposal is to use this for ABCD light depending on sequence (For example CDAB is also possible to show)
|
||||
|
||||
// Traffic light infos
|
||||
// status info
|
||||
// Right
|
||||
// Left
|
||||
// TODO: uint8_t PORTUPPERCASE will be replaced by according PORTx
|
||||
// Parsing of DIGITS command
|
||||
if (ReceivedCommand.d.cmd == 0b0)
|
||||
{
|
||||
// Parse command only if is same side as this panel (or comamnd says to override)
|
||||
if (ReceivedCommand.d.sideOverride || ReceivedCommand.d.side == cfg.PanelSide)
|
||||
if ((ReceivedCommand.d.sideOverride || ReceivedCommand.d.side) == cfg.PanelSide)
|
||||
{
|
||||
uint8_t PORTLEFT = segment[ReceivedCommand.d.lDigit];
|
||||
uint8_t PORTMID = segment[ReceivedCommand.d.mDigit];
|
||||
uint8_t PORTRIGHT = segment[ReceivedCommand.d.rDigit];
|
||||
CATPORT(MIDDIGIT_PORT) = segment[ReceivedCommand.d.mDigit];
|
||||
CATPORT(RIGHTDIGIT_PORT) = segment[ReceivedCommand.d.rDigit];
|
||||
// Turn on dot between minutes and seconds only if count is in minutes and its digit is a representable value (not dash)
|
||||
if (ReceivedCommand.d.lDigit != CHAR_DASH && ReceivedCommand.d.minutes)
|
||||
{
|
||||
CATPORT(LEFTDIGIT_PORT) = segment[ReceivedCommand.d.lDigit] | DOTS_bm;
|
||||
}
|
||||
else
|
||||
CATPORT(LEFTDIGIT_PORT) = segment[ReceivedCommand.d.lDigit];
|
||||
}
|
||||
|
||||
// Turn on : between minutes and seconds only if count is in minutes and its digit is a representable value (not dash)
|
||||
if (ReceivedCommand.d.lDigit != CHAR_DASH && ReceivedCommand.d.minutes)
|
||||
uint8_t PORTCOMMA |= _BV(7);
|
||||
}
|
||||
// Parsing of TRAFFIC command
|
||||
else if (ReceivedCommand.t.cmd < 0b111)
|
||||
{
|
||||
// Set buzzer depending on mute switch
|
||||
if (cfg.BuzzerStatus == BUZZER_ON)
|
||||
{
|
||||
uint8_t PORTBUZZER |= ReceivedCommand.t.buzzer;
|
||||
digitalWrite(HORNP_PIN, ReceivedCommand.t.buzzer);
|
||||
}
|
||||
|
||||
// Set Traffic lights depending on side switch
|
||||
if (cfg.PanelSide == RIGHT)
|
||||
uint8_t PORTSEMAPHORE |= ReceivedCommand.t.TrafficLightRight;
|
||||
{
|
||||
digitalWrite(GREENP_PIN, ReceivedCommand.t.TrafficLightRight | _BV(0)); // green right side
|
||||
digitalWrite(ORANGEP_PIN, ReceivedCommand.t.TrafficLightRight | _BV(1)); // orange right side
|
||||
digitalWrite(REDP_PIN, ReceivedCommand.t.TrafficLightRight | _BV(2)); // red right side
|
||||
}
|
||||
else
|
||||
uint8_t PORTSEMAPHORE |= ReceivedCommand.t.TrafficLightLeft;
|
||||
|
||||
uint8_t PORTABCD |= ReceivedCommand.t.ArcherGroups;
|
||||
// at the moment ignore EF, not in this panel
|
||||
{
|
||||
digitalWrite(GREENP_PIN, ReceivedCommand.t.TrafficLightLeft | _BV(0)); // green left side
|
||||
digitalWrite(ORANGEP_PIN, ReceivedCommand.t.TrafficLightLeft | _BV(1)); // orange left side
|
||||
digitalWrite(REDP_PIN, ReceivedCommand.t.TrafficLightLeft | _BV(2)); // red left side
|
||||
}
|
||||
|
||||
// Set ABCD(EF)
|
||||
digitalWrite(A_PIN, ReceivedCommand.t.ArcherGroups | _BV(0)); //A
|
||||
digitalWrite(B_PIN, ReceivedCommand.t.ArcherGroups | _BV(1)); //B
|
||||
digitalWrite(C_PIN, ReceivedCommand.t.ArcherGroups | _BV(2)); //C
|
||||
digitalWrite(D_PIN, ReceivedCommand.t.ArcherGroups | _BV(3)); //D
|
||||
// EF not implemented in this hardware
|
||||
/*
|
||||
digitalWrite(6, (((statevalue >> 7) & B00000111) != 2) and (trafficvalue & 0x4000)); //E
|
||||
digitalWrite(7, (((statevalue >> 7) & B00000111) != 2) and (trafficvalue & 0x8000)); //F
|
||||
digitalWrite(A15, (((statevalue >> 7) & B00000111) == 2) and (trafficvalue & 0x4000)); //green right arrow for fita finals
|
||||
digitalWrite(39, (((statevalue >> 7) & B00000111) == 2) and (trafficvalue & 0x8000)); //green left arrow for fita finals
|
||||
*/
|
||||
|
||||
// Set not{A,B,C,D,(E,F)}
|
||||
if (cfg.abcd != 6)
|
||||
{
|
||||
uint8_t notABCD_on = 0;
|
||||
// not A is on if archer group A is not selected
|
||||
digitalWrite(notA_PIN, cfg.GroupsNumber > 1 && !(ReceivedCommand.t.ArcherGroups & _BV(0)));
|
||||
|
||||
// not B ~ not D are on if groups are effectively present and are not selected
|
||||
if (cfg.competition != 2 && cfg.competition != 4)
|
||||
{
|
||||
digitalWrite(notA_PIN, cfg.GroupsNumber > 1 && !(ReceivedCommand.t.ArcherGroups & _BV(1)));
|
||||
digitalWrite(notA_PIN, cfg.GroupsNumber > 2 && !(ReceivedCommand.t.ArcherGroups & _BV(2)));
|
||||
digitalWrite(notA_PIN, cfg.GroupsNumber > 3 && !(ReceivedCommand.t.ArcherGroups & _BV(3)));
|
||||
}
|
||||
else
|
||||
{
|
||||
digitalWrite(notB_PIN, LOW);
|
||||
digitalWrite(notC_PIN, LOW);
|
||||
digitalWrite(notD_PIN, LOW);
|
||||
}
|
||||
|
||||
// EF not implemented in this hardware
|
||||
/*
|
||||
digitalWrite(8, (((((statevalue >> 13) & B00000111) < 4) ? LOW : HIGH) and ((((statevalue >> 7) & B00000111) == 2) ? LOW : HIGH) and ((((statevalue >> 7) & B00000111) == 4) ? LOW : HIGH) and (not(trafficvalue & 0x4000) ? HIGH : LOW))); //notE. Is on if Archer E exist but it is not his/her turn to shoot
|
||||
digitalWrite(9, (((((statevalue >> 13) & B00000111) < 5) ? LOW : HIGH) and ((((statevalue >> 7) & B00000111) == 2) ? LOW : HIGH) and ((((statevalue >> 7) & B00000111) == 4) ? LOW : HIGH) and (not(trafficvalue & 0x8000) ? HIGH : LOW))); //notF. Is on if Archer F exist but it is not his/her turn to shoot
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
digitalWrite(notA_PIN, HIGH);
|
||||
digitalWrite(notB_PIN, HIGH);
|
||||
digitalWrite(notC_PIN, HIGH);
|
||||
digitalWrite(notD_PIN, HIGH);
|
||||
|
||||
// EF not implemented in this hardware
|
||||
/*
|
||||
digitalWrite(8, (blinkl));
|
||||
digitalWrite(9, (blinkl));
|
||||
*/
|
||||
}
|
||||
}
|
||||
// Parsing of STATE command
|
||||
else if (ReceivedCommand.s.cmd == 0b1111)
|
||||
|
@ -213,36 +260,6 @@ void loop()
|
|||
cfg.competition = ReceivedCommand.s.competition;
|
||||
cfg.GroupsNumber = ReceivedCommand.s.GroupsNumber;
|
||||
}
|
||||
// not managed endnr value
|
||||
/*
|
||||
lefend = ((endnrvalue >> 4) & B00001111);
|
||||
midend = ((endnrvalue >> 8) & B00001111);
|
||||
rigend = ((endnrvalue >> 12) & B00001111);
|
||||
if (lefend == 15)
|
||||
{
|
||||
comend = lefend;
|
||||
}
|
||||
else
|
||||
{
|
||||
comend = midend;
|
||||
};
|
||||
|
||||
digitalWrite(24, ((segment[comend] & 0x001)) ? HIGH : LOW); //left combined end digit segment A
|
||||
digitalWrite(26, ((segment[comend] & 0x002)) ? HIGH : LOW); //left combined end digit segment B
|
||||
digitalWrite(28, ((segment[comend] & 0x004)) ? HIGH : LOW); //left combined end digit segment C
|
||||
digitalWrite(30, ((segment[comend] & 0x008)) ? HIGH : LOW); //left combined end digit segment D
|
||||
digitalWrite(32, ((segment[comend] & 0x010)) ? HIGH : LOW); //left combined end digit segment E
|
||||
digitalWrite(34, ((segment[comend] & 0x020)) ? HIGH : LOW); //left combined end digit segment F
|
||||
digitalWrite(36, ((segment[comend] & 0x040)) ? HIGH : LOW); //left combined end digit segment G
|
||||
|
||||
digitalWrite(40, ((segment[rigend] & 0x001)) ? HIGH : LOW); //right end digit segment A
|
||||
digitalWrite(42, ((segment[rigend] & 0x002)) ? HIGH : LOW); //right end digit segment B
|
||||
digitalWrite(44, ((segment[rigend] & 0x004)) ? HIGH : LOW); //right end digit segment C
|
||||
digitalWrite(46, ((segment[rigend] & 0x008)) ? HIGH : LOW); //right end digit segment D
|
||||
digitalWrite(48, ((segment[rigend] & 0x010)) ? HIGH : LOW); //right end digit segment E
|
||||
digitalWrite(50, ((segment[rigend] & 0x020)) ? HIGH : LOW); //right end digit segment F
|
||||
digitalWrite(52, ((segment[rigend] & 0x040)) ? HIGH : LOW); //right end digit segment G
|
||||
*/
|
||||
}
|
||||
else // if (char) digit != '\n'
|
||||
{
|
||||
|
@ -250,35 +267,62 @@ void loop()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//last 2 bits of trafic value show the number of archers. In this way we can determine notA, notB, notC and notD
|
||||
/*
|
||||
if (blinkk == 0)
|
||||
// This feature is not implemented in this hardware
|
||||
/*
|
||||
lefend = ((endnrvalue >> 4) & B00001111);
|
||||
midend = ((endnrvalue >> 8) & B00001111);
|
||||
rigend = ((endnrvalue >> 12) & B00001111);
|
||||
if (lefend == 15)
|
||||
{
|
||||
blinkk = 300;
|
||||
comend = lefend;
|
||||
}
|
||||
else
|
||||
{
|
||||
blinkk--;
|
||||
};
|
||||
if (blinkkk == 0)
|
||||
{
|
||||
blinkkk = 2400;
|
||||
}
|
||||
else
|
||||
{
|
||||
blinkkk--;
|
||||
};
|
||||
if (blinkkk > 1200)
|
||||
{
|
||||
blinkr = 0;
|
||||
blinkl = (blinkk > 200);
|
||||
}
|
||||
else
|
||||
{
|
||||
blinkr = (blinkk > 200);
|
||||
blinkl = 0;
|
||||
comend = midend;
|
||||
};
|
||||
|
||||
digitalWrite(24, ((segment[comend] & 0x001)) ? HIGH : LOW); //left combined end digit segment A
|
||||
digitalWrite(26, ((segment[comend] & 0x002)) ? HIGH : LOW); //left combined end digit segment B
|
||||
digitalWrite(28, ((segment[comend] & 0x004)) ? HIGH : LOW); //left combined end digit segment C
|
||||
digitalWrite(30, ((segment[comend] & 0x008)) ? HIGH : LOW); //left combined end digit segment D
|
||||
digitalWrite(32, ((segment[comend] & 0x010)) ? HIGH : LOW); //left combined end digit segment E
|
||||
digitalWrite(34, ((segment[comend] & 0x020)) ? HIGH : LOW); //left combined end digit segment F
|
||||
digitalWrite(36, ((segment[comend] & 0x040)) ? HIGH : LOW); //left combined end digit segment G
|
||||
|
||||
digitalWrite(40, ((segment[rigend] & 0x001)) ? HIGH : LOW); //right end digit segment A
|
||||
digitalWrite(42, ((segment[rigend] & 0x002)) ? HIGH : LOW); //right end digit segment B
|
||||
digitalWrite(44, ((segment[rigend] & 0x004)) ? HIGH : LOW); //right end digit segment C
|
||||
digitalWrite(46, ((segment[rigend] & 0x008)) ? HIGH : LOW); //right end digit segment D
|
||||
digitalWrite(48, ((segment[rigend] & 0x010)) ? HIGH : LOW); //right end digit segment E
|
||||
digitalWrite(50, ((segment[rigend] & 0x020)) ? HIGH : LOW); //right end digit segment F
|
||||
digitalWrite(52, ((segment[rigend] & 0x040)) ? HIGH : LOW); //right end digit segment G
|
||||
*/
|
||||
|
||||
// This feature is not implemented in this hardware
|
||||
/*
|
||||
//Read buttons
|
||||
buttonvalue = 0;
|
||||
// if (digitalRead(A4)){buttonvalue=5;};
|
||||
// if (digitalRead(A3)){buttonvalue=4;};
|
||||
// if (digitalRead(A0)){buttonvalue=1;}; //next
|
||||
// if (digitalRead(A1)){buttonvalue=2;};
|
||||
// if (digitalRead(A2)){buttonvalue=3;};
|
||||
if (loop1 == 0)
|
||||
{
|
||||
if (buttonvalue != remember1)
|
||||
{
|
||||
Serial.print(buttonvalue);
|
||||
delay(3);
|
||||
remember1 = buttonvalue;
|
||||
loop1 = 15;
|
||||
//digitalWrite(2, 1);
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
delay(10);
|
||||
//if (loop1>7){blinkr=1;};
|
||||
loop1--;
|
||||
};
|
||||
*/
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue