Initial commit.
This commit is contained in:
		
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					.pioenvs
 | 
				
			||||||
 | 
					.piolibdeps
 | 
				
			||||||
 | 
					.clang_complete
 | 
				
			||||||
 | 
					.gcc-flags.json
 | 
				
			||||||
							
								
								
									
										67
									
								
								.travis.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								.travis.yml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,67 @@
 | 
				
			|||||||
 | 
					# Continuous Integration (CI) is the practice, in software
 | 
				
			||||||
 | 
					# engineering, of merging all developer working copies with a shared mainline
 | 
				
			||||||
 | 
					# several times a day < https://docs.platformio.org/page/ci/index.html >
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Documentation:
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# * Travis CI Embedded Builds with PlatformIO
 | 
				
			||||||
 | 
					#   < https://docs.travis-ci.com/user/integration/platformio/ >
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# * PlatformIO integration with Travis CI
 | 
				
			||||||
 | 
					#   < https://docs.platformio.org/page/ci/travis.html >
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# * User Guide for `platformio ci` command
 | 
				
			||||||
 | 
					#   < https://docs.platformio.org/page/userguide/cmd_ci.html >
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Please choose one of the following templates (proposed below) and uncomment
 | 
				
			||||||
 | 
					# it (remove "# " before each line) or use own configuration according to the
 | 
				
			||||||
 | 
					# Travis CI documentation (see above).
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Template #1: General project. Test it using existing `platformio.ini`.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# language: python
 | 
				
			||||||
 | 
					# python:
 | 
				
			||||||
 | 
					#     - "2.7"
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# sudo: false
 | 
				
			||||||
 | 
					# cache:
 | 
				
			||||||
 | 
					#     directories:
 | 
				
			||||||
 | 
					#         - "~/.platformio"
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# install:
 | 
				
			||||||
 | 
					#     - pip install -U platformio
 | 
				
			||||||
 | 
					#     - platformio update
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# script:
 | 
				
			||||||
 | 
					#     - platformio run
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Template #2: The project is intended to be used as a library with examples.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# language: python
 | 
				
			||||||
 | 
					# python:
 | 
				
			||||||
 | 
					#     - "2.7"
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# sudo: false
 | 
				
			||||||
 | 
					# cache:
 | 
				
			||||||
 | 
					#     directories:
 | 
				
			||||||
 | 
					#         - "~/.platformio"
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# env:
 | 
				
			||||||
 | 
					#     - PLATFORMIO_CI_SRC=path/to/test/file.c
 | 
				
			||||||
 | 
					#     - PLATFORMIO_CI_SRC=examples/file.ino
 | 
				
			||||||
 | 
					#     - PLATFORMIO_CI_SRC=path/to/test/directory
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# install:
 | 
				
			||||||
 | 
					#     - pip install -U platformio
 | 
				
			||||||
 | 
					#     - platformio update
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# script:
 | 
				
			||||||
 | 
					#     - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N
 | 
				
			||||||
							
								
								
									
										3
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					# FREMO Fast Clock
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This is a fast clock implementation based on a 2.4GHz wireless transmission layer based on NRF24 controllers.
 | 
				
			||||||
							
								
								
									
										39
									
								
								include/readme.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								include/readme.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					This directory is intended for project header files.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					A header file is a file containing C declarations and macro definitions
 | 
				
			||||||
 | 
					to be shared between several project source files. You request the use of a
 | 
				
			||||||
 | 
					header file in your project source file (C, C++, etc) located in `src` folder
 | 
				
			||||||
 | 
					by including it, with the C preprocessing directive `#include'.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```src/main.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "header.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main (void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					 ...
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Including a header file produces the same results as copying the header file
 | 
				
			||||||
 | 
					into each source file that needs it. Such copying would be time-consuming
 | 
				
			||||||
 | 
					and error-prone. With a header file, the related declarations appear
 | 
				
			||||||
 | 
					in only one place. If they need to be changed, they can be changed in one
 | 
				
			||||||
 | 
					place, and programs that include the header file will automatically use the
 | 
				
			||||||
 | 
					new version when next recompiled. The header file eliminates the labor of
 | 
				
			||||||
 | 
					finding and changing all the copies as well as the risk that a failure to
 | 
				
			||||||
 | 
					find one copy will result in inconsistencies within a program.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In C, the usual convention is to give header files names that end with `.h'.
 | 
				
			||||||
 | 
					It is most portable to use only letters, digits, dashes, and underscores in
 | 
				
			||||||
 | 
					header file names, and at most one dot.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Read more about using header files in official GCC documentation:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* Include Syntax
 | 
				
			||||||
 | 
					* Include Operation
 | 
				
			||||||
 | 
					* Once-Only Headers
 | 
				
			||||||
 | 
					* Computed Includes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
 | 
				
			||||||
							
								
								
									
										46
									
								
								lib/readme.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								lib/readme.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					This directory is intended for project specific (private) libraries.
 | 
				
			||||||
 | 
					PlatformIO will compile them to static libraries and link into executable file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The source code of each library should be placed in a an own separate directory
 | 
				
			||||||
 | 
					("lib/your_library_name/[here are source files]").
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For example, see a structure of the following two libraries `Foo` and `Bar`:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					|--lib
 | 
				
			||||||
 | 
					|  |
 | 
				
			||||||
 | 
					|  |--Bar
 | 
				
			||||||
 | 
					|  |  |--docs
 | 
				
			||||||
 | 
					|  |  |--examples
 | 
				
			||||||
 | 
					|  |  |--src
 | 
				
			||||||
 | 
					|  |     |- Bar.c
 | 
				
			||||||
 | 
					|  |     |- Bar.h
 | 
				
			||||||
 | 
					|  |  |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
 | 
				
			||||||
 | 
					|  |
 | 
				
			||||||
 | 
					|  |--Foo
 | 
				
			||||||
 | 
					|  |  |- Foo.c
 | 
				
			||||||
 | 
					|  |  |- Foo.h
 | 
				
			||||||
 | 
					|  |
 | 
				
			||||||
 | 
					|  |- readme.txt --> THIS FILE
 | 
				
			||||||
 | 
					|
 | 
				
			||||||
 | 
					|- platformio.ini
 | 
				
			||||||
 | 
					|--src
 | 
				
			||||||
 | 
					   |- main.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					and a contents of `src/main.c`:
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					#include <Foo.h>
 | 
				
			||||||
 | 
					#include <Bar.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main (void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  ...
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PlatformIO Library Dependency Finder will find automatically dependent
 | 
				
			||||||
 | 
					libraries scanning project source files.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					More information about PlatformIO Library Dependency Finder
 | 
				
			||||||
 | 
					- https://docs.platformio.org/page/librarymanager/ldf.html
 | 
				
			||||||
							
								
								
									
										32
									
								
								platformio.ini
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								platformio.ini
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
				
			|||||||
 | 
					; PlatformIO Project Configuration File
 | 
				
			||||||
 | 
					;
 | 
				
			||||||
 | 
					;   Build options: build flags, source filter
 | 
				
			||||||
 | 
					;   Upload options: custom upload port, speed and extra flags
 | 
				
			||||||
 | 
					;   Library options: dependencies, extra library storages
 | 
				
			||||||
 | 
					;   Advanced options: extra scripting
 | 
				
			||||||
 | 
					;
 | 
				
			||||||
 | 
					; Please visit documentation for the other options and examples
 | 
				
			||||||
 | 
					; https://docs.platformio.org/page/projectconf.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[platformio]
 | 
				
			||||||
 | 
					env_default = nanoatmega168
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[env:pro8MHzatmega328]
 | 
				
			||||||
 | 
					platform = atmelavr
 | 
				
			||||||
 | 
					board = pro8MHzatmega328
 | 
				
			||||||
 | 
					framework = arduino
 | 
				
			||||||
 | 
					lib_deps = ArduinoJson, RadioHead, Adafruit SSD1306, Adafruit_GFX
 | 
				
			||||||
 | 
					build_flags = -D WITH_DISPLAY
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[env:nanoatmega168]
 | 
				
			||||||
 | 
					platform = atmelavr
 | 
				
			||||||
 | 
					board = nanoatmega168
 | 
				
			||||||
 | 
					framework = arduino
 | 
				
			||||||
 | 
					lib_deps = ArduinoJson, RadioHead
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[env:nanoatmega328]
 | 
				
			||||||
 | 
					platform = atmelavr
 | 
				
			||||||
 | 
					board = nanoatmega328
 | 
				
			||||||
 | 
					framework = arduino
 | 
				
			||||||
 | 
					lib_deps = ArduinoJson, RadioHead, Adafruit SSD1306, Adafruit_GFX
 | 
				
			||||||
 | 
					build_flags = -D WITH_DISPLAY
 | 
				
			||||||
							
								
								
									
										14
									
								
								src/clockMsg.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/clockMsg.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					#ifndef clockMsg_h_included
 | 
				
			||||||
 | 
					#define clockMsg_h_included
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <Arduino.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct clockMsg_s {
 | 
				
			||||||
 | 
					  uint8_t msgType;
 | 
				
			||||||
 | 
					  uint8_t hour;
 | 
				
			||||||
 | 
					  uint8_t minute;
 | 
				
			||||||
 | 
					  uint8_t second;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					#define msgType_Clock 'c'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										231
									
								
								src/main.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										231
									
								
								src/main.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,231 @@
 | 
				
			|||||||
 | 
					#include <Arduino.h>
 | 
				
			||||||
 | 
					#include <SPI.h>
 | 
				
			||||||
 | 
					#include <RH_NRF24.h>
 | 
				
			||||||
 | 
					#include <RHDatagram.h>
 | 
				
			||||||
 | 
					#include "clockMsg.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if WITH_DISPLAY
 | 
				
			||||||
 | 
					#include <Adafruit_GFX.h>
 | 
				
			||||||
 | 
					#include <Adafruit_SSD1306.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define OLED_RESET /*4*/
 | 
				
			||||||
 | 
					Adafruit_SSD1306 display(OLED_RESET);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Singleton instance of the radio driver
 | 
				
			||||||
 | 
					RH_NRF24 nrf24(8, 10); // (CSN, CE)
 | 
				
			||||||
 | 
					// RH_NRF24 nrf24(8, 7); // use this to be electrically compatible with Mirf
 | 
				
			||||||
 | 
					// RH_NRF24 nrf24(8, 10);// For Leonardo, need explicit SS pin
 | 
				
			||||||
 | 
					// RH_NRF24 nrf24(8, 7); // For RFM73 on Anarduino Mini
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define nRF_Channel 1
 | 
				
			||||||
 | 
					#define THIS_ADRESS 0 // uint8_t address of this node
 | 
				
			||||||
 | 
					// Address RH_BROADCAST_ADDRESS  can be used for broadcasts as destination
 | 
				
			||||||
 | 
					RHDatagram Datagram(nrf24, THIS_ADRESS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct clockMsg_s clockMsg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int masterConfigPin = 2;
 | 
				
			||||||
 | 
					static boolean isMaster = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// relays for client's physical clock
 | 
				
			||||||
 | 
					int relay1pin = 5;
 | 
				
			||||||
 | 
					int relay2pin = 6;
 | 
				
			||||||
 | 
					// configs:
 | 
				
			||||||
 | 
					int holdRelay_ms = 150;
 | 
				
			||||||
 | 
					int minRelayOffTime_ms = 80;
 | 
				
			||||||
 | 
					boolean relayActiveLow = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct {
 | 
				
			||||||
 | 
					  uint8_t hour;
 | 
				
			||||||
 | 
					  uint8_t minute;
 | 
				
			||||||
 | 
					  uint8_t second;
 | 
				
			||||||
 | 
					} displayedTime;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void updateRelays(struct clockMsg_s currentTime) {
 | 
				
			||||||
 | 
					  // to move forward for one minute, one of the relays is turned
 | 
				
			||||||
 | 
					  // on for holdRelay_ms milliseconds, then turned off. Next minute,
 | 
				
			||||||
 | 
					  // the other relay is turned on for holdRelay_ms.
 | 
				
			||||||
 | 
					  static long lastChange_ms = 0;
 | 
				
			||||||
 | 
					  static boolean relay1WasActiveLast = false;
 | 
				
			||||||
 | 
					  static enum {relayIdle, relayOn, relayOff} relayStatus = relayIdle;
 | 
				
			||||||
 | 
					  long current_ms = millis();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Serial.print("currentTime="); Serial.print(currentTime.hour); Serial.print(":"); Serial.print(currentTime.minute); Serial.print(":"); Serial.println(currentTime.second);
 | 
				
			||||||
 | 
					  if (relayStatus == relayIdle) {
 | 
				
			||||||
 | 
					    if (!((currentTime.hour % 12) == displayedTime.hour && currentTime.minute == displayedTime.minute)) {
 | 
				
			||||||
 | 
					      // change updateRelays
 | 
				
			||||||
 | 
					      digitalWrite(relay1WasActiveLast ? relay2pin : relay1pin, relayActiveLow ? LOW : HIGH);
 | 
				
			||||||
 | 
					      digitalWrite(relay1WasActiveLast ? relay1pin : relay2pin, relayActiveLow ? HIGH : LOW);
 | 
				
			||||||
 | 
					      Serial.print("Relay "); Serial.print(relay1WasActiveLast ? 2 : 1); Serial.print(relayActiveLow ? ": LOW, " : ": HIGH, ");
 | 
				
			||||||
 | 
					      Serial.print("Relay "); Serial.print(relay1WasActiveLast ? 1 : 2); Serial.println(relayActiveLow ? ": HIGH" : ": LOW");
 | 
				
			||||||
 | 
					      Serial.print("last change: "); Serial.print(lastChange_ms); Serial.print(", current: "); Serial.print(current_ms);
 | 
				
			||||||
 | 
					      Serial.println(", new relay status: ON");
 | 
				
			||||||
 | 
					      relay1WasActiveLast = !relay1WasActiveLast;
 | 
				
			||||||
 | 
					      lastChange_ms = current_ms;
 | 
				
			||||||
 | 
					      relayStatus = relayOn;
 | 
				
			||||||
 | 
					      displayedTime.minute++;
 | 
				
			||||||
 | 
					      if (displayedTime.minute >= 60) {
 | 
				
			||||||
 | 
					        displayedTime.minute = 0;
 | 
				
			||||||
 | 
					        displayedTime.hour++;
 | 
				
			||||||
 | 
					        if (displayedTime.hour >= 12) {
 | 
				
			||||||
 | 
					          displayedTime.hour = 0;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      Serial.print("displayedTime="); Serial.print(displayedTime.hour); Serial.print(":"); Serial.println(displayedTime.minute);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  } else if (relayStatus == relayOn && current_ms > lastChange_ms + holdRelay_ms) {
 | 
				
			||||||
 | 
					    digitalWrite(relay1pin, relayActiveLow ? HIGH : LOW);
 | 
				
			||||||
 | 
					    digitalWrite(relay2pin, relayActiveLow ? HIGH : LOW);
 | 
				
			||||||
 | 
					    Serial.print("Relay 1: "); Serial.print(relayActiveLow ? "HIGH, " : "LOW, ");
 | 
				
			||||||
 | 
					    Serial.print("Relay 2: "); Serial.println(relayActiveLow ? "HIGH" : "LOW");
 | 
				
			||||||
 | 
					    Serial.print("last change: "); Serial.print(lastChange_ms); Serial.print(", current: "); Serial.print(current_ms);
 | 
				
			||||||
 | 
					    Serial.println(", new relay status: OFF");
 | 
				
			||||||
 | 
					    lastChange_ms = current_ms;
 | 
				
			||||||
 | 
					    relayStatus = relayOff;
 | 
				
			||||||
 | 
					  } else if (relayStatus == relayOff && current_ms > lastChange_ms + minRelayOffTime_ms) {
 | 
				
			||||||
 | 
					    Serial.print("last change: "); Serial.print(lastChange_ms); Serial.print(", current: "); Serial.print(current_ms);
 | 
				
			||||||
 | 
					    Serial.println(", new relay status: IDLE");
 | 
				
			||||||
 | 
					    lastChange_ms = current_ms;
 | 
				
			||||||
 | 
					    relayStatus = relayIdle;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void setup() {
 | 
				
			||||||
 | 
					  Serial.begin(9600);
 | 
				
			||||||
 | 
					  while (!Serial)
 | 
				
			||||||
 | 
					    ; // wait for serial port to connect. Needed for Leonardo only
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // what is our role?
 | 
				
			||||||
 | 
					  pinMode(masterConfigPin, INPUT);
 | 
				
			||||||
 | 
					  pinMode(relay1pin, OUTPUT);
 | 
				
			||||||
 | 
					  pinMode(relay2pin, OUTPUT);
 | 
				
			||||||
 | 
					  displayedTime.hour = 0;
 | 
				
			||||||
 | 
					  displayedTime.minute = 0;
 | 
				
			||||||
 | 
					  displayedTime.second = 0;
 | 
				
			||||||
 | 
					  if (!digitalRead(masterConfigPin)) {
 | 
				
			||||||
 | 
					    isMaster = true;
 | 
				
			||||||
 | 
					    Serial.println("In Master-Mode");
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    isMaster = false;
 | 
				
			||||||
 | 
					    Serial.println("In Client-Mode");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!Datagram.init())
 | 
				
			||||||
 | 
					    Serial.println("Init datagram with nrf24 failed");
 | 
				
			||||||
 | 
					  // Defaults after init are 2.402 GHz (channel 2), 2Mbps, 0dBm
 | 
				
			||||||
 | 
					  /*if (!nrf24.setChannel(nRF_Channel))
 | 
				
			||||||
 | 
					    Serial.println("setChannel failed");
 | 
				
			||||||
 | 
					  if (!nrf24.setRF(RH_NRF24::DataRate2Mbps, RH_NRF24::TransmitPower0dBm))
 | 
				
			||||||
 | 
					    Serial.println("setRF failed");
 | 
				
			||||||
 | 
					    */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if WITH_DISPLAY
 | 
				
			||||||
 | 
					  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
 | 
				
			||||||
 | 
					  display.display();
 | 
				
			||||||
 | 
					  delay(2000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Clear the buffer.
 | 
				
			||||||
 | 
					  display.clearDisplay();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // draw a single pixel
 | 
				
			||||||
 | 
					  display.drawPixel(10, 10, WHITE);
 | 
				
			||||||
 | 
					  // Show the display buffer on the hardware.
 | 
				
			||||||
 | 
					  // NOTE: You _must_ call display after making any drawing commands
 | 
				
			||||||
 | 
					  // to make them visible on the display hardware!
 | 
				
			||||||
 | 
					  display.display();
 | 
				
			||||||
 | 
					  delay(2000);
 | 
				
			||||||
 | 
					  display.clearDisplay();
 | 
				
			||||||
 | 
					  display.setTextSize(1);
 | 
				
			||||||
 | 
					  display.setTextColor(WHITE);
 | 
				
			||||||
 | 
					  display.setCursor(0,0);
 | 
				
			||||||
 | 
					  display.println("Hello, world!");
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void masterLoop()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  static unsigned long nextTimeTick_ms = millis();
 | 
				
			||||||
 | 
					  static unsigned long updateEvery_ms = 1000;
 | 
				
			||||||
 | 
					  static uint8_t hour=0, minute=0, second=0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (Datagram.available())
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    // Should be a message for us now
 | 
				
			||||||
 | 
					    uint8_t buf[RH_NRF24_MAX_MESSAGE_LEN];
 | 
				
			||||||
 | 
					    uint8_t len = sizeof(buf);
 | 
				
			||||||
 | 
					    uint8_t from, to, id, flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (Datagram.recvfrom(buf, &len, &from, &to, &id, &flags)) {
 | 
				
			||||||
 | 
					      Serial.print("got request: ");
 | 
				
			||||||
 | 
					      Serial.println((char*)buf);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      Serial.println("*** Datagram.recvfrom failed");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    // prepare clock info
 | 
				
			||||||
 | 
					    if (nextTimeTick_ms < millis()) {
 | 
				
			||||||
 | 
					      nextTimeTick_ms += updateEvery_ms;
 | 
				
			||||||
 | 
					      second++;
 | 
				
			||||||
 | 
					      if (second >= 60) {
 | 
				
			||||||
 | 
					        second -= 60;
 | 
				
			||||||
 | 
					        minute++;
 | 
				
			||||||
 | 
					        if (minute >= 60) {
 | 
				
			||||||
 | 
					          minute -= 60;
 | 
				
			||||||
 | 
					          hour++;
 | 
				
			||||||
 | 
					          if (hour >= 24) {
 | 
				
			||||||
 | 
					            hour -= 24;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      clockMsg.msgType = msgType_Clock;
 | 
				
			||||||
 | 
					      clockMsg.hour = hour;
 | 
				
			||||||
 | 
					      clockMsg.minute = minute;
 | 
				
			||||||
 | 
					      clockMsg.second = second;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // send clock info as a broadcast message
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (Datagram.sendto((uint8_t *) &clockMsg, sizeof(clockMsg), RH_BROADCAST_ADDRESS)) {
 | 
				
			||||||
 | 
					        Serial.print(hour); Serial.print(":");
 | 
				
			||||||
 | 
					        Serial.print(minute); Serial.print(":");
 | 
				
			||||||
 | 
					        Serial.print(second); Serial.print(" - ");
 | 
				
			||||||
 | 
					        Serial.println("Sent new clock tick");
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void clientLoop()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  // if (nrf24.available())
 | 
				
			||||||
 | 
					  if (Datagram.available())
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    // Should be a message for us now
 | 
				
			||||||
 | 
					    uint8_t buf[RH_NRF24_MAX_MESSAGE_LEN];
 | 
				
			||||||
 | 
					    uint8_t len = sizeof(buf);
 | 
				
			||||||
 | 
					    uint8_t from, to, id, flags;
 | 
				
			||||||
 | 
					    if (Datagram.recvfrom(buf, &len, &from, &to, &id, &flags)) {
 | 
				
			||||||
 | 
					      if (len == sizeof(clockMsg) && buf[0]==msgType_Clock) {
 | 
				
			||||||
 | 
					        Serial.print("Clock Msg: ");
 | 
				
			||||||
 | 
					        memcpy(&clockMsg, buf, sizeof(clockMsg));
 | 
				
			||||||
 | 
					        Serial.print(" h:m:s="); Serial.print(clockMsg.hour); Serial.print(":"); Serial.print(clockMsg.minute); Serial.print(":"); Serial.println(clockMsg.second);
 | 
				
			||||||
 | 
					        updateRelays(clockMsg);
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        Serial.print("got request: ");
 | 
				
			||||||
 | 
					        Serial.println((char*)buf);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      Serial.println("*** Datagram.recvfrom failed");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void loop() {
 | 
				
			||||||
 | 
					  if (isMaster) { masterLoop(); }
 | 
				
			||||||
 | 
					  else { clientLoop(); }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user