/* CountDown Timer version using three arduinos Miha needs: - countdown seconds display from 15:00:00 (hh:mm:ss) = 6 digits = 42 segments - when 00:00:00 reached - wait for 9 hours = jump to 9:00:00 and count down invisibly -> toggle some visibility variable to hidden - show 00:00:00 blinking! Maybe write something -> POLICE - when invisible counting reaches 0:00:00 - jump to 15:00:00 - toggle countdown visibly to visible Follow these steps to connect Arduino UNOs using I2C: Connect pins A4 and A5 between Arduinos The GND line has to be common for all three Arduinos You can also connect the 5V pins and power all three from one The following code is split in three parts: the master code, first slave code and second slave code which will run differently on three Arduinos. Define the master first arduino as 1, first slave as 2, second slave as 3 LED strips take 250mA - 4 parallel lines of 12 leds (12 x 3V = 36V) // 39V? 6 x 7 = 42 * 0.25A = 10A // ok Normally strips are used via 42V current limited PSU We have 24V AC PSUs - shows 27V - ca be paralleled - full rectification and filtering brings us to 37V Current limiting resistors should take U=R*I voltage - some voltage stabilisation could be needed Master and slave will use pins 0,1,2,3,4,5,6 and 7,8,9,10,11,12,13 Pin 14 is LED blinker On master we use 15,16,17 for other stuff: - pin 15 for tone() seconds tick (use of tone() function will interfere with PWM output on pins 3 and 11) - used also fo alarm, clock type alarm - pin 16 NoonButt; use this button to set the time at noon - pin 17 SpeedButt - accelerates countdown 100 times - toggle between 5V (normal) and 0V (fast) On slave (maybe) - pin 15 as driver for constant or blinking dots between numbers (two dots have 24V led strips connected in series) */ // define some identity to this arduino const byte master_slave = 1; // this is master - first arduino - does the counting - makes the sound //const byte master_slave = 2; // this is first slave - second arduino - minutes //const byte master_slave = 3; // this is second slave - third arduino - hours const bool test = false; // true speeds up countdown - relates to master only const bool testalarm = false; // true will bring countdown close to zero const bool testserial = false; //true print serial info // define to show leading zeros const bool showzeros = true; //true to show leading zeros // define to show zeros at non-visible period const bool shownightzeros = false; //true to show zeros at night - false for empty // define the top value to count down from // visible countdown 150000 = 15:00:00 = 15 hours, 240000 = 24:00:00 = 24 hours, 10000 = 1:00:00 = 1 hour #define VISIBLE 150000 // hidden countdown 90000 = 9:00:00 = 9 hours #define HIDDEN 90000 // visible countdown starts at 6 o'clock, ends at 21 o'clock = 15 hours // ring alarm or not const bool AlarmRing = false; const int AlarmLength=30; // in seconds - how many seconds to keep alarm at 0 reached count // optional seconds blinking const byte Led = 14; bool LedOn = false; // sound and alarm - only on master // tik-tak // use tone function const byte Speaker = 15; // Pin 9 connected to MOSFET etc // notes to play const int notes[] = { 1047, 988, 880, 523 }; const int duration = 100; // play notes for 100 ms // noon sets visible countnumber to 150000 - 60000 = 90000 #define NOON 90000 const byte NoonButt = 16; // define the test speed-up activated with pushbutton bool speedup = false; // false = default for normal countdown - only on master const byte SpeedButt = 17; // on master - to test or set //time increment unsigned long TimeStep = 1000000; // microseconds // check timestamps for seconds unsigned long TimeStamp=micros(); // remember visible countdown or hidden (false) bool CountVisible = true; // BS: we reduced the number to seconds - instead of centimes of seconds // we need from 15:00:00 -> six numbers - last (or first?) two not needed long int visiblenumber=VISIBLE; long int hiddennumber=HIDDEN; // start with visible long int countnumber = visiblenumber; // on slave we check for change in number received long int prevcountnumber = countnumber; int AlarmCount=0; // counter to keep alarm at 0 reached count // variable to define that alarm is on or off bool SignalOut = false; // redefine master again in setup according to the role set bool master = true; // define the i2c slave addresses - master needs to know where to send data // just use the decimal numbers; call it as address[master_slave - 2] to get to first index const byte address[] = { 2, 3 }; // second and third arduino // pins: // A4=18, A5=19 is i2c - it is doubled on the other side on arduino R3 // 18 pins available per UNO // we need: 6 * 7 = 42 pins for 6 full digits // pins: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 // pins: A0, A1, A2, A3 = 14, 15, 16, 17 // pwm pins for sound: 5, 6 and 9, 10 // all pins set as outputs const byte all_pins[18] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; // digits go from right to left -> to become hh:mm:ss // define the digits as a b c d e f g array of pins for master UNO -> 1 const byte digit_1[7] = { 0, 1, 2, 3, 4, 5, 6}; const byte digit_2[7] = { 7, 8, 9, 10, 11, 12, 13}; // not used here 14, 15, 16 and 17 // use master arduino for any additional functions - peep sound, sirene sound, blinks, etc. // these will be sent to i2c second UNO - first slave UNO -> 2 const byte digit_3[7] = { 0, 1, 2, 3, 4, 5, 6}; const byte digit_4[7] = { 7, 8, 9, 10, 11, 12, 13}; // not used here 14, 15, 16 and 17 // these will be sent to i2c third UNO - second slave UNO -> 3 const byte digit_5[7] = { 0, 1, 2, 3, 4, 5, 6}; const byte digit_6[7] = { 7, 8, 9, 10, 11, 12, 13}; // not used here 14, 15, 16 and 17 // define the letter for POLICE const byte text[6][7] = { // a, b, c, d, e, f, g { 1, 0, 0, 1, 1, 1, 1}, // first digit - arduino 1 = E { 1, 0, 0, 1, 1, 1, 0}, // second digit - arduino 1 = C { 0, 0, 0, 0, 1, 1, 0}, // third digit - arduino 2 = I { 0, 0, 0, 1, 1, 1, 0}, // fourth digit - arduino 2 = L { 1, 1, 1, 1, 1, 1, 0}, // fifth digit - arduino 3 = O { 1, 1, 0, 0, 1, 1, 1}, // sixth digit - arduino 3 = P }; // Variables to store individual numbers - from seconds to hours // BS: we use six numbers byte sixnum=0; // hours byte fivenum=0; // hours byte fournum=0; // minutes byte thirdnum=0; // minutes byte secondnum=0; // seconds byte firstnum=0; // seconds // Include the required Wire library for I2C #include // variable to be sent and received over i2c byte data[6]={0,0,0,0,0,0}; // timestamp to check when I2C data received //volatile unsigned long ReceiveTime = millis(); String prevnumchar = ""; void setup() { // redefine if arduino is master if(master_slave > 1) { // master_slave 2 or 3 master = false; } else { // master_slave 1 master = true; } if(master) { // Start the I2C Bus as Master Wire.begin(); } else { // slave // Start the I2C Bus as Slave on address number of master_slave Wire.begin(address[master_slave - 2]); // from 2 become 0 // Attach a function to trigger when something is received. Wire.onReceive(receiveEvent); } // initialize pins as outputs for(int i=0; i