├── python_receiver ├── caster.conf.sample └── receiver.py ├── usage_examples ├── File │ ├── caster.conf.sample │ ├── run.sh │ ├── sending.txt │ ├── send.py │ └── receive.py ├── BTC │ ├── run.sh │ ├── caster.conf.sample │ ├── send.py │ ├── bitcoin_rpc_class.py │ └── receive.py └── LTC │ ├── run.sh │ ├── caster.conf.sample │ ├── send.py │ ├── bitcoin_rpc_class.py │ └── receive.py ├── lib ├── LMIC-Arduino_ID852 │ ├── doc │ │ ├── LMiC-v1.5.pdf │ │ ├── README.txt │ │ └── release-notes.txt │ ├── src │ │ ├── lmic.h │ │ ├── hal │ │ │ ├── hal.h │ │ │ └── hal.cpp │ │ ├── lmic │ │ │ ├── hal.h │ │ │ ├── config.h │ │ │ ├── oslmic.c │ │ │ └── oslmic.h │ │ └── aes │ │ │ ├── other.c │ │ │ └── ideetron │ │ │ └── AES-128_V10.cpp │ ├── library.properties │ ├── .library.json │ └── examples │ │ ├── raw │ │ └── raw.ino │ │ ├── ttn-otaa │ │ └── ttn-otaa.ino │ │ └── ttn-abp │ │ └── ttn-abp.ino ├── ESP8266_SSD1306_ID562 │ ├── resources │ │ ├── FontTool.png │ │ ├── DemoFrame1.jpg │ │ ├── DemoFrame2.jpg │ │ ├── DemoFrame3.jpg │ │ ├── DemoFrame4.jpg │ │ ├── xbmPreview.png │ │ ├── SPI_version.jpg │ │ └── glyphEditor.png │ ├── examples │ │ ├── SSD1306ClockDemo │ │ │ ├── images.h │ │ │ └── SSD1306ClockDemo.ino │ │ ├── SSD1306SimpleDemo │ │ │ ├── images.h │ │ │ └── SSD1306SimpleDemo.ino │ │ ├── SSD1306TwoScreenDemo │ │ │ ├── images.h │ │ │ └── SSD1306TwoScreenDemo.ino │ │ ├── SSD1306UiDemo │ │ │ ├── images.h │ │ │ └── SSD1306UiDemo.ino │ │ ├── SSD1306OTADemo │ │ │ └── SSD1306OTADemo.ino │ │ └── SSD1306DrawingDemo │ │ │ └── SSD1306DrawingDemo.ino │ ├── library.properties │ ├── .travis.yml │ ├── UPGRADE-4.0.md │ ├── library.json │ ├── .library.json │ ├── license │ ├── SH1106.h │ ├── SSD1306.h │ ├── SH1106Spi.h │ ├── SH1106Brzo.h │ ├── UPGRADE-3.0.md │ ├── SSD1306Spi.h │ ├── SH1106Wire.h │ ├── SSD1306Brzo.h │ ├── SSD1306Wire.h │ ├── OLEDDisplayUi.h │ └── OLEDDisplay.h └── readme.txt ├── .gitignore ├── src ├── hardware.h ├── config.h ├── ttn_config.h.sample └── config.cpp ├── platformio.ini ├── LICENSE ├── .travis.yml └── README.md /python_receiver/caster.conf.sample: -------------------------------------------------------------------------------- 1 | [TTN] 2 | app_id: 3 | access_key: 4 | -------------------------------------------------------------------------------- /usage_examples/File/caster.conf.sample: -------------------------------------------------------------------------------- 1 | [TTN] 2 | app_id: 3 | access_key: 4 | -------------------------------------------------------------------------------- /usage_examples/BTC/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | python3 send.py & 4 | python3 receive.py 5 | -------------------------------------------------------------------------------- /usage_examples/File/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | python3 send.py & 4 | python3 receive.py 5 | -------------------------------------------------------------------------------- /usage_examples/LTC/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | python3 send.py & 4 | python3 receive.py 5 | -------------------------------------------------------------------------------- /lib/LMIC-Arduino_ID852/doc/LMiC-v1.5.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/valerio-vaccaro/LoraCaster/HEAD/lib/LMIC-Arduino_ID852/doc/LMiC-v1.5.pdf -------------------------------------------------------------------------------- /usage_examples/File/sending.txt: -------------------------------------------------------------------------------- 1 | You have to accept the fact that sometimes you are the pigeon, and sometimes you are the statue 2 | 01234567890 3 | -------------------------------------------------------------------------------- /lib/ESP8266_SSD1306_ID562/resources/FontTool.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/valerio-vaccaro/LoraCaster/HEAD/lib/ESP8266_SSD1306_ID562/resources/FontTool.png -------------------------------------------------------------------------------- /lib/ESP8266_SSD1306_ID562/resources/DemoFrame1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/valerio-vaccaro/LoraCaster/HEAD/lib/ESP8266_SSD1306_ID562/resources/DemoFrame1.jpg -------------------------------------------------------------------------------- /lib/ESP8266_SSD1306_ID562/resources/DemoFrame2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/valerio-vaccaro/LoraCaster/HEAD/lib/ESP8266_SSD1306_ID562/resources/DemoFrame2.jpg -------------------------------------------------------------------------------- /lib/ESP8266_SSD1306_ID562/resources/DemoFrame3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/valerio-vaccaro/LoraCaster/HEAD/lib/ESP8266_SSD1306_ID562/resources/DemoFrame3.jpg -------------------------------------------------------------------------------- /lib/ESP8266_SSD1306_ID562/resources/DemoFrame4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/valerio-vaccaro/LoraCaster/HEAD/lib/ESP8266_SSD1306_ID562/resources/DemoFrame4.jpg -------------------------------------------------------------------------------- /lib/ESP8266_SSD1306_ID562/resources/xbmPreview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/valerio-vaccaro/LoraCaster/HEAD/lib/ESP8266_SSD1306_ID562/resources/xbmPreview.png -------------------------------------------------------------------------------- /lib/ESP8266_SSD1306_ID562/resources/SPI_version.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/valerio-vaccaro/LoraCaster/HEAD/lib/ESP8266_SSD1306_ID562/resources/SPI_version.jpg -------------------------------------------------------------------------------- /lib/ESP8266_SSD1306_ID562/resources/glyphEditor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/valerio-vaccaro/LoraCaster/HEAD/lib/ESP8266_SSD1306_ID562/resources/glyphEditor.png -------------------------------------------------------------------------------- /lib/LMIC-Arduino_ID852/src/lmic.h: -------------------------------------------------------------------------------- 1 | #ifdef __cplusplus 2 | extern "C"{ 3 | #endif 4 | 5 | #include "lmic/lmic.h" 6 | 7 | #ifdef __cplusplus 8 | } 9 | #endif 10 | -------------------------------------------------------------------------------- /usage_examples/BTC/caster.conf.sample: -------------------------------------------------------------------------------- 1 | [BTC] 2 | host: localhost 3 | port: 18332 4 | username: user 5 | password: password 6 | wallet: wallet.dat 7 | address: 8 | 9 | [TTN] 10 | app_id: 11 | access_key: 12 | -------------------------------------------------------------------------------- /usage_examples/LTC/caster.conf.sample: -------------------------------------------------------------------------------- 1 | [LTC] 2 | host: localhost 3 | port: 19332 4 | username: user 5 | password: password 6 | wallet: wallet.dat 7 | address: 8 | 9 | [TTN] 10 | app_id: 11 | access_key: 12 | -------------------------------------------------------------------------------- /lib/LMIC-Arduino_ID852/doc/README.txt: -------------------------------------------------------------------------------- 1 | DISCLAIMER: 2 | Please note that the software is provided AS IS and we cannot 3 | provide support for optimizations, adaptations, integration, 4 | ports to other platforms or device drivers! 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .pioenvs 2 | .piolibdeps 3 | .clang_complete 4 | .gcc-flags.json 5 | src/ttn_config.h 6 | *.pyc 7 | python_receiver/caster.conf 8 | usage_examples/BTC/caster.conf 9 | usage_examples/LTC/caster.conf 10 | usage_examples/file/caster.conf 11 | -------------------------------------------------------------------------------- /src/hardware.h: -------------------------------------------------------------------------------- 1 | #ifndef HARDWARE_H 2 | #define HARDWARE_H 3 | 4 | #include 5 | #include 6 | 7 | 8 | // Led 9 | #define LEDPIN 2 // TTGO 10 | //#define LEDPIN 25 // HELTEC 11 | 12 | // Display 13 | #define OLED_I2C_ADDR 0x3C 14 | #define OLED_RESET 16 15 | #define OLED_SDA 4 16 | #define OLED_SCL 15 17 | 18 | #endif /* HARDWARE_H */ 19 | -------------------------------------------------------------------------------- /src/config.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H 2 | #define CONFIG_H 3 | 4 | #include 5 | #include 6 | 7 | #define FORMAT_SPIFFS_IF_FAILED true 8 | 9 | bool defaultConfig(); 10 | bool loadConfig(int* conf_b, int* conf_r, int* conf_w, int* conf_f); 11 | bool saveConfig(int conf_b, int conf_r, int conf_w, int conf_f); 12 | 13 | #endif /* CONFIG_H */ 14 | -------------------------------------------------------------------------------- /lib/LMIC-Arduino_ID852/library.properties: -------------------------------------------------------------------------------- 1 | name=LMIC-Arduino 2 | version=1.5.0+arduino-2 3 | author=IBM 4 | maintainer=Matthijs Kooijman 5 | sentence=Arduino port of the LMIC (LoraWAN-in-C, formerly LoraMAC-in-C) framework provided by IBM. 6 | paragraph=Supports SX1272/SX1276 and HopeRF RFM92/RFM95 tranceivers 7 | category=Communication 8 | url=https://github.com/matthijskooijman/arduino-lmic 9 | architectures=* 10 | -------------------------------------------------------------------------------- /lib/ESP8266_SSD1306_ID562/examples/SSD1306ClockDemo/images.h: -------------------------------------------------------------------------------- 1 | const unsigned char activeSymbol[] PROGMEM = { 2 | B00000000, 3 | B00000000, 4 | B00011000, 5 | B00100100, 6 | B01000010, 7 | B01000010, 8 | B00100100, 9 | B00011000 10 | }; 11 | 12 | const unsigned char inactiveSymbol[] PROGMEM = { 13 | B00000000, 14 | B00000000, 15 | B00000000, 16 | B00000000, 17 | B00011000, 18 | B00011000, 19 | B00000000, 20 | B00000000 21 | }; 22 | -------------------------------------------------------------------------------- /lib/ESP8266_SSD1306_ID562/library.properties: -------------------------------------------------------------------------------- 1 | name=ESP8266 and ESP32 Oled Driver for SSD1306 display 2 | version=4.0.0 3 | author=Daniel Eichhorn, Fabrice Weinberg 4 | maintainer=Daniel Eichhorn 5 | sentence=A I2C display driver for SSD1306 oled displays connected to an ESP8266 or ESP32 6 | paragraph=A I2C display driver for SSD1306 oled displays connected to an ESP8266 or ESP32 7 | category=Display 8 | url=https://github.com/ThingPulse/esp8266-oled-ssd1306 9 | architectures=esp8266,esp32 10 | -------------------------------------------------------------------------------- /platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; http://docs.platformio.org/page/projectconf.html 10 | 11 | [platformio] 12 | data_dir = ./data 13 | 14 | [env:heltec_wifi_lora_32] 15 | platform = espressif32 16 | board = heltec_wifi_lora_32 17 | framework = arduino 18 | #lib_deps = 562, 852 19 | -------------------------------------------------------------------------------- /usage_examples/File/send.py: -------------------------------------------------------------------------------- 1 | import configparser 2 | import serial 3 | from time import sleep 4 | 5 | config = configparser.RawConfigParser() 6 | config.read('caster.conf') 7 | 8 | file = open('sending.txt', 'r') 9 | buff = file.read() 10 | file.close() 11 | 12 | ser = serial.Serial('/dev/cu.SLAB_USBtoUART', 115200, timeout=1) 13 | 14 | message = 'p'+buff.encode('utf-8').hex()+'!' 15 | for c in message: 16 | print(c.encode('utf8'), end='') 17 | ser.write(c.encode('utf8')) 18 | sleep(0.001) 19 | 20 | message = 'S' 21 | print(message.encode('utf8')) 22 | ser.write(message.encode('utf8')) 23 | 24 | while(True): 25 | print(ser.read().decode('utf-8'), end='') 26 | 27 | ser.close() 28 | -------------------------------------------------------------------------------- /lib/ESP8266_SSD1306_ID562/.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - "2.7" 4 | 5 | # Cache PlatformIO packages using Travis CI container-based infrastructure 6 | sudo: false 7 | cache: 8 | directories: 9 | - "~/.platformio" 10 | 11 | env: 12 | - PLATFORMIO_CI_SRC=examples/SSD1306UiDemo 13 | - PLATFORMIO_CI_SRC=examples/SSD1306SimpleDemo 14 | - PLATFORMIO_CI_SRC=examples/SSD1306DrawingDemo 15 | - PLATFORMIO_CI_SRC=examples/SSD1306OTADemo 16 | - PLATFORMIO_CI_SRC=examples/SSD1306ClockDemo 17 | - PLATFORMIO_CI_SRC=examples/SSD1306TwoScreenDemo 18 | 19 | 20 | install: 21 | - pip install -U platformio 22 | - platformio lib install 44 23 | 24 | script: 25 | - platformio ci --lib="." --board=nodemcuv2 26 | -------------------------------------------------------------------------------- /lib/ESP8266_SSD1306_ID562/UPGRADE-4.0.md: -------------------------------------------------------------------------------- 1 | # Upgrade from 3.x to 4.0 2 | 3 | There are changes that breaks compatibility with older versions. 4 | 5 | 1. You'll have to change data type for all your binary resources such as images and fonts from 6 | 7 | ```c 8 | const char MySymbol[] PROGMEM = { 9 | ``` 10 | 11 | to 12 | 13 | ```c 14 | const uint8_t MySymbol[] PROGMEM = { 15 | ``` 16 | 17 | 1. Arguments of `setContrast` from `char` to `uint8_t` 18 | 19 | ```c++ 20 | void OLEDDisplay::setContrast(char contrast, char precharge, char comdetect); 21 | ``` 22 | 23 | to 24 | 25 | ```c++ 26 | void OLEDDisplay::setContrast(uint8_t contrast, uint8_t precharge, uint8_t comdetect); 27 | ``` 28 | -------------------------------------------------------------------------------- /lib/ESP8266_SSD1306_ID562/library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ESP8266_SSD1306", 3 | "version": "4.0.0", 4 | "keywords": "ssd1306, oled, display, i2c", 5 | "description": "A I2C display driver for SSD1306 oled displays connected to an ESP8266 or ESP32", 6 | "repository": 7 | { 8 | "type": "git", 9 | "url": "https://github.com/squix78/esp8266-oled-ssd1306.git" 10 | }, 11 | "authors": 12 | [ 13 | { 14 | "name": "Daniel Eichhorn, ThingPulse", 15 | "email": "squix78@gmail.com", 16 | "url": "https://thingpulse.com" 17 | }, 18 | { 19 | "name": "Fabrice Weinberg", 20 | "email": "fabrice@weinberg.me" 21 | } 22 | ], 23 | "frameworks": "arduino", 24 | "platforms": [ 25 | "espressif8266", 26 | "espressif32" 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /lib/LMIC-Arduino_ID852/doc/release-notes.txt: -------------------------------------------------------------------------------- 1 | ============================================================================== 2 | LMIC VERSION 1.4 (17-Mar-2015) 3 | ------------------------------- 4 | 5 | - changed API: inverted port indicator flag in LMIC.txrxFlags 6 | (now TXRX_PORT, previously TXRX_NOPORT) 7 | 8 | - fixed offset OFF_CFLIST constant 9 | 10 | - changed CRC-16 algorithm for beacons to CCITT(XMODEM) polynomial 11 | 12 | - fixed radio driver (low data rate optimization for SF11+SF12 only for BW125) 13 | 14 | - fixed timer rollover handling in job queue 15 | 16 | ============================================================================== 17 | LMIC VERSION 1.5 (8-May-2015) 18 | ------------------------------ 19 | 20 | - fixed condition in convFreq() 21 | 22 | - fixed freq*100 bug and freq==0 bug for CFList 23 | 24 | - fixed TX scheduling bug 25 | 26 | - better support for GNU compiler toolchain 27 | 28 | ============================================================================== 29 | -------------------------------------------------------------------------------- /lib/LMIC-Arduino_ID852/src/hal/hal.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2015 Matthijs Kooijman 3 | * All rights reserved. This program and the accompanying materials 4 | * are made available under the terms of the Eclipse Public License v1.0 5 | * which accompanies this distribution, and is available at 6 | * http://www.eclipse.org/legal/epl-v10.html 7 | * 8 | * This the HAL to run LMIC on top of the Arduino environment. 9 | *******************************************************************************/ 10 | #ifndef _hal_hal_h_ 11 | #define _hal_hal_h_ 12 | 13 | static const int NUM_DIO = 3; 14 | 15 | struct lmic_pinmap { 16 | u1_t nss; 17 | u1_t rxtx; 18 | u1_t rst; 19 | u1_t dio[NUM_DIO]; 20 | }; 21 | 22 | // Use this for any unused pins. 23 | const u1_t LMIC_UNUSED_PIN = 0xff; 24 | 25 | // Declared here, to be defined an initialized by the application 26 | extern const lmic_pinmap lmic_pins; 27 | 28 | #endif // _hal_hal_h_ 29 | -------------------------------------------------------------------------------- /lib/readme.txt: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for the project specific (private) libraries. 3 | PlatformIO will compile them to static libraries and link to executable file. 4 | 5 | The source code of each library should be placed in separate directory, like 6 | "lib/private_lib/[here are source files]". 7 | 8 | For example, see how can be organized `Foo` and `Bar` libraries: 9 | 10 | |--lib 11 | | |--Bar 12 | | | |--docs 13 | | | |--examples 14 | | | |--src 15 | | | |- Bar.c 16 | | | |- Bar.h 17 | | |--Foo 18 | | | |- Foo.c 19 | | | |- Foo.h 20 | | |- readme.txt --> THIS FILE 21 | |- platformio.ini 22 | |--src 23 | |- main.c 24 | 25 | Then in `src/main.c` you should use: 26 | 27 | #include 28 | #include 29 | 30 | // rest H/C/CPP code 31 | 32 | PlatformIO will find your libraries automatically, configure preprocessor's 33 | include paths and build them. 34 | 35 | More information about PlatformIO Library Dependency Finder 36 | - http://docs.platformio.org/page/librarymanager/ldf.html 37 | -------------------------------------------------------------------------------- /lib/ESP8266_SSD1306_ID562/.library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ESP8266_SSD1306", 3 | "repository": { 4 | "url": "https://github.com/squix78/esp8266-oled-ssd1306.git", 5 | "type": "git" 6 | }, 7 | "platforms": [ 8 | "espressif32", 9 | "espressif8266" 10 | ], 11 | "frameworks": [ 12 | "arduino" 13 | ], 14 | "version": "4.0.0", 15 | "authors": [ 16 | { 17 | "maintainer": false, 18 | "name": "Daniel Eichhorn, ThingPulse", 19 | "url": "https://thingpulse.com", 20 | "email": "squix78@gmail.com" 21 | }, 22 | { 23 | "url": null, 24 | "maintainer": false, 25 | "email": "fabrice@weinberg.me", 26 | "name": "Fabrice Weinberg" 27 | } 28 | ], 29 | "keywords": [ 30 | "oled", 31 | "i2c", 32 | "display", 33 | "ssd1306" 34 | ], 35 | "id": 562, 36 | "description": "A I2C display driver for SSD1306 oled displays connected to an ESP8266 or ESP32" 37 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Valerio Vaccaro 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /lib/ESP8266_SSD1306_ID562/license: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 by Daniel Eichhorn 4 | Copyright (c) 2016 by Fabrice Weinberg 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | 24 | See more at http://blog.squix.ch 25 | -------------------------------------------------------------------------------- /usage_examples/BTC/send.py: -------------------------------------------------------------------------------- 1 | import configparser 2 | from bitcoin_rpc_class import RPCHost 3 | import serial 4 | from time import sleep 5 | 6 | config = configparser.RawConfigParser() 7 | config.read('caster.conf') 8 | rpcHost = config.get('BTC', 'host') 9 | rpcPort = config.get('BTC', 'port') 10 | rpcUser = config.get('BTC', 'username') 11 | rpcPassword = config.get('BTC', 'password') 12 | address = config.get('BTC', 'address') 13 | rpcWallet = config.get('BTC', 'wallet') 14 | serverURL = 'http://' + rpcUser + ':' + rpcPassword + '@'+rpcHost+':' + str(rpcPort)+'/wallet/' + rpcWallet 15 | #serverURL = 'http://' + rpcUser + ':' + rpcPassword + '@'+rpcHost+':' + str(rpcPort) 16 | 17 | host = RPCHost(serverURL) 18 | 19 | res = host.call('createrawtransaction', [], {address:0.001}) 20 | res = host.call('fundrawtransaction', res) 21 | res = host.call('signrawtransaction', res['hex']) 22 | 23 | ser = serial.Serial('/dev/cu.SLAB_USBtoUART', 115200, timeout=1) 24 | 25 | message = 'p'+res['hex']+'!' 26 | for c in message: 27 | print(c.encode('utf8'), end='') 28 | ser.write(c.encode('utf8')) 29 | sleep(0.001) 30 | 31 | message = 'S' 32 | print(message.encode('utf8')) 33 | ser.write(message.encode('utf8')) 34 | 35 | while(True): 36 | print(ser.read().decode('utf-8'), end='') 37 | 38 | ser.close() 39 | -------------------------------------------------------------------------------- /usage_examples/LTC/send.py: -------------------------------------------------------------------------------- 1 | import configparser 2 | from bitcoin_rpc_class import RPCHost 3 | import serial 4 | from time import sleep 5 | 6 | config = configparser.RawConfigParser() 7 | config.read('caster.conf') 8 | rpcHost = config.get('LTC', 'host') 9 | rpcPort = config.get('LTC', 'port') 10 | rpcUser = config.get('LTC', 'username') 11 | rpcPassword = config.get('LTC', 'password') 12 | address = config.get('LTC', 'address') 13 | rpcWallet = config.get('LTC', 'wallet') 14 | serverURL = 'http://' + rpcUser + ':' + rpcPassword + '@'+rpcHost+':' + str(rpcPort)+'/wallet/' + rpcWallet 15 | #serverURL = 'http://' + rpcUser + ':' + rpcPassword + '@'+rpcHost+':' + str(rpcPort) 16 | 17 | host = RPCHost(serverURL) 18 | 19 | res = host.call('createrawtransaction', [], {address:0.001}) 20 | res = host.call('fundrawtransaction', res) 21 | res = host.call('signrawtransaction', res['hex']) 22 | 23 | ser = serial.Serial('/dev/cu.SLAB_USBtoUART', 115200, timeout=1) 24 | 25 | message = 'p'+res['hex']+'!' 26 | for c in message: 27 | print(c.encode('utf8'), end='') 28 | ser.write(c.encode('utf8')) 29 | sleep(0.001) 30 | 31 | message = 'S' 32 | print(message.encode('utf8')) 33 | ser.write(message.encode('utf8')) 34 | 35 | while(True): 36 | print(ser.read().decode('utf-8'), end='') 37 | 38 | ser.close() 39 | -------------------------------------------------------------------------------- /lib/LMIC-Arduino_ID852/.library.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Arduino port of the LMIC (LoraWAN-in-C, formerly LoraMAC-in-C) framework provided by IBM.", 3 | "repository": { 4 | "url": "https://github.com/matthijskooijman/arduino-lmic", 5 | "type": "git" 6 | }, 7 | "platforms": [ 8 | "atmelavr", 9 | "atmelsam", 10 | "espressif8266", 11 | "intel_arc32", 12 | "microchippic32", 13 | "nordicnrf51", 14 | "teensy", 15 | "timsp430" 16 | ], 17 | "export": { 18 | "exclude": [ 19 | "extras", 20 | "docs", 21 | "tests", 22 | "test", 23 | "*.doxyfile", 24 | "*.pdf" 25 | ], 26 | "include": null 27 | }, 28 | "authors": [ 29 | { 30 | "maintainer": false, 31 | "name": "IBM", 32 | "url": null, 33 | "email": null 34 | }, 35 | { 36 | "maintainer": true, 37 | "name": "Matthijs Kooijman", 38 | "url": null, 39 | "email": "matthijs@stdin.nl" 40 | } 41 | ], 42 | "keywords": [ 43 | "communication" 44 | ], 45 | "id": 852, 46 | "name": "LMIC-Arduino", 47 | "frameworks": [ 48 | "arduino" 49 | ], 50 | "version": "1.5.0+arduino-2", 51 | "homepage": null 52 | } -------------------------------------------------------------------------------- /src/ttn_config.h.sample: -------------------------------------------------------------------------------- 1 | /*===================================================================================* 2 | ::: ... :::::::.. :::. .,-::::: :::. .::::::.:::::::::::: 3 | ;;; .;;;;;;;. ;;;;``;;;; ;;`;; ,;;;'````' ;;`;; ;;;` `;;;;;;;;'''' 4 | [[[ ,[[ [[,[[[,/[[[' ,[[ '[[, [[[ ,[[ '[[, '[==/[[[[, [[ 5 | $$' $$$, $$$$$$$$$c c$$$cc$$$c $$$ c$$$cc$$$c ''' $ $$ 6 | o88oo,.__"888,_ _,88P888b "88bo,888 888,`88bo,__,o, 888 888,88b dP 88, 7 | """"YUMMM "YMMMMMP" MMMM "W" YMM ""` "YUMMMMMP"YMM ""` "YMmMY" MMM 8 | *===================================================================================* 9 | LoraCast - ttn configurations 10 | MIT License - Copyright (c) 2018 Valerio Vaccaro 11 | Based on https://github.com/gonzalocasas/arduino-uno-dragino-lorawan/blob/master/LICENSE 12 | Based on examples from https://github.com/matthijskooijman/arduino-lmic 13 | *===================================================================================*/ 14 | 15 | // TTN configurations 16 | static u1_t NWKSKEY[16] = { ... }; // Paste here the key in MSB format 17 | static u1_t APPSKEY[16] = { ... }; // Paste here the key in MSB format 18 | static u4_t DEVADDR = 0x...; // Put here the device id in hexadecimal form. 19 | 20 | void os_getArtEui (u1_t* buf) { } 21 | void os_getDevEui (u1_t* buf) { } 22 | void os_getDevKey (u1_t* buf) { } 23 | -------------------------------------------------------------------------------- /usage_examples/BTC/bitcoin_rpc_class.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import time, requests, json 3 | 4 | class RPCHost(object): 5 | def __init__(self, url): 6 | self._session = requests.Session() 7 | self._url = url 8 | self._headers = {'content-type': 'application/json'} 9 | 10 | def call(self, rpcMethod, *params): 11 | payload = json.dumps({"method": rpcMethod, "params": list(params), "jsonrpc": "2.0"}) 12 | tries = 5 13 | hadConnectionFailures = False 14 | while True: 15 | try: 16 | response = self._session.post(self._url, headers=self._headers, data=payload) 17 | except requests.exceptions.ConnectionError: 18 | tries -= 1 19 | if tries == 0: 20 | raise Exception('Failed to connect for remote procedure call.') 21 | hadFailedConnections = True 22 | print("Couldn't connect for remote procedure call, will sleep for five seconds and then try again ({} more tries)".format(tries)) 23 | time.sleep(10) 24 | else: 25 | if hadConnectionFailures: 26 | print('Connected for remote procedure call after retry.') 27 | break 28 | if not response.status_code in (200, 500): 29 | raise Exception('RPC connection failure: ' + str(response.status_code) + ' ' + response.reason) 30 | responseJSON = response.json() 31 | if 'error' in responseJSON and responseJSON['error'] != None: 32 | raise Exception('Error in RPC call: ' + str(responseJSON['error'])) 33 | return responseJSON['result'] 34 | -------------------------------------------------------------------------------- /usage_examples/LTC/bitcoin_rpc_class.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import time, requests, json 3 | 4 | class RPCHost(object): 5 | def __init__(self, url): 6 | self._session = requests.Session() 7 | self._url = url 8 | self._headers = {'content-type': 'application/json'} 9 | 10 | def call(self, rpcMethod, *params): 11 | payload = json.dumps({"method": rpcMethod, "params": list(params), "jsonrpc": "2.0"}) 12 | tries = 5 13 | hadConnectionFailures = False 14 | while True: 15 | try: 16 | response = self._session.post(self._url, headers=self._headers, data=payload) 17 | except requests.exceptions.ConnectionError: 18 | tries -= 1 19 | if tries == 0: 20 | raise Exception('Failed to connect for remote procedure call.') 21 | hadFailedConnections = True 22 | print("Couldn't connect for remote procedure call, will sleep for five seconds and then try again ({} more tries)".format(tries)) 23 | time.sleep(10) 24 | else: 25 | if hadConnectionFailures: 26 | print('Connected for remote procedure call after retry.') 27 | break 28 | if not response.status_code in (200, 500): 29 | raise Exception('RPC connection failure: ' + str(response.status_code) + ' ' + response.reason) 30 | responseJSON = response.json() 31 | if 'error' in responseJSON and responseJSON['error'] != None: 32 | raise Exception('Error in RPC call: ' + str(responseJSON['error'])) 33 | return responseJSON['result'] 34 | -------------------------------------------------------------------------------- /lib/ESP8266_SSD1306_ID562/SH1106.h: -------------------------------------------------------------------------------- 1 | /** 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2018 by ThingPulse, Daniel Eichhorn 5 | * Copyright (c) 2018 by Fabrice Weinberg 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | * 25 | * ThingPulse invests considerable time and money to develop these open source libraries. 26 | * Please support us by buying our products (and not the clones) from 27 | * https://thingpulse.com 28 | * 29 | */ 30 | 31 | #ifndef SH1106_h 32 | #define SH1106_h 33 | #include "SH1106Wire.h" 34 | 35 | // For make SH1106 an alias for SH1106Wire 36 | typedef SH1106Wire SH1106; 37 | 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /lib/ESP8266_SSD1306_ID562/SSD1306.h: -------------------------------------------------------------------------------- 1 | /** 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2018 by ThingPulse, Daniel Eichhorn 5 | * Copyright (c) 2018 by Fabrice Weinberg 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | * 25 | * ThingPulse invests considerable time and money to develop these open source libraries. 26 | * Please support us by buying our products (and not the clones) from 27 | * https://thingpulse.com 28 | * 29 | */ 30 | 31 | #ifndef SSD1306_h 32 | #define SSD1306_h 33 | #include "SSD1306Wire.h" 34 | 35 | // For legacy support make SSD1306 an alias for SSD1306 36 | typedef SSD1306Wire SSD1306; 37 | 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # Continuous Integration (CI) is the practice, in software 2 | # engineering, of merging all developer working copies with a shared mainline 3 | # several times a day < https://docs.platformio.org/page/ci/index.html > 4 | # 5 | # Documentation: 6 | # 7 | # * Travis CI Embedded Builds with PlatformIO 8 | # < https://docs.travis-ci.com/user/integration/platformio/ > 9 | # 10 | # * PlatformIO integration with Travis CI 11 | # < https://docs.platformio.org/page/ci/travis.html > 12 | # 13 | # * User Guide for `platformio ci` command 14 | # < https://docs.platformio.org/page/userguide/cmd_ci.html > 15 | # 16 | # 17 | # Please choose one of the following templates (proposed below) and uncomment 18 | # it (remove "# " before each line) or use own configuration according to the 19 | # Travis CI documentation (see above). 20 | # 21 | 22 | 23 | # 24 | # Template #1: General project. Test it using existing `platformio.ini`. 25 | # 26 | 27 | # language: python 28 | # python: 29 | # - "2.7" 30 | # 31 | # sudo: false 32 | # cache: 33 | # directories: 34 | # - "~/.platformio" 35 | # 36 | # install: 37 | # - pip install -U platformio 38 | # - platformio update 39 | # 40 | # script: 41 | # - platformio run 42 | 43 | 44 | # 45 | # Template #2: The project is intended to be used as a library with examples. 46 | # 47 | 48 | # language: python 49 | # python: 50 | # - "2.7" 51 | # 52 | # sudo: false 53 | # cache: 54 | # directories: 55 | # - "~/.platformio" 56 | # 57 | # env: 58 | # - PLATFORMIO_CI_SRC=path/to/test/file.c 59 | # - PLATFORMIO_CI_SRC=examples/file.ino 60 | # - PLATFORMIO_CI_SRC=path/to/test/directory 61 | # 62 | # install: 63 | # - pip install -U platformio 64 | # - platformio update 65 | # 66 | # script: 67 | # - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N 68 | -------------------------------------------------------------------------------- /lib/ESP8266_SSD1306_ID562/examples/SSD1306SimpleDemo/images.h: -------------------------------------------------------------------------------- 1 | #define WiFi_Logo_width 60 2 | #define WiFi_Logo_height 36 3 | const uint8_t WiFi_Logo_bits[] PROGMEM = { 4 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 5 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00, 6 | 0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 7 | 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00, 8 | 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 9 | 0xFF, 0x03, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 10 | 0x00, 0xFF, 0xFF, 0xFF, 0x07, 0xC0, 0x83, 0x01, 0x80, 0xFF, 0xFF, 0xFF, 11 | 0x01, 0x00, 0x07, 0x00, 0xC0, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0C, 0x00, 12 | 0xC0, 0xFF, 0xFF, 0x7C, 0x00, 0x60, 0x0C, 0x00, 0xC0, 0x31, 0x46, 0x7C, 13 | 0xFC, 0x77, 0x08, 0x00, 0xE0, 0x23, 0xC6, 0x3C, 0xFC, 0x67, 0x18, 0x00, 14 | 0xE0, 0x23, 0xE4, 0x3F, 0x1C, 0x00, 0x18, 0x00, 0xE0, 0x23, 0x60, 0x3C, 15 | 0x1C, 0x70, 0x18, 0x00, 0xE0, 0x03, 0x60, 0x3C, 0x1C, 0x70, 0x18, 0x00, 16 | 0xE0, 0x07, 0x60, 0x3C, 0xFC, 0x73, 0x18, 0x00, 0xE0, 0x87, 0x70, 0x3C, 17 | 0xFC, 0x73, 0x18, 0x00, 0xE0, 0x87, 0x70, 0x3C, 0x1C, 0x70, 0x18, 0x00, 18 | 0xE0, 0x87, 0x70, 0x3C, 0x1C, 0x70, 0x18, 0x00, 0xE0, 0x8F, 0x71, 0x3C, 19 | 0x1C, 0x70, 0x18, 0x00, 0xC0, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x08, 0x00, 20 | 0xC0, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x0C, 0x00, 0x80, 0xFF, 0xFF, 0x1F, 21 | 0x00, 0x00, 0x06, 0x00, 0x80, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x07, 0x00, 22 | 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 23 | 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x00, 24 | 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 25 | 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 26 | 0x00, 0x00, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 27 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 28 | }; 29 | -------------------------------------------------------------------------------- /lib/ESP8266_SSD1306_ID562/examples/SSD1306TwoScreenDemo/images.h: -------------------------------------------------------------------------------- 1 | #define WiFi_Logo_width 60 2 | #define WiFi_Logo_height 36 3 | const uint8_t WiFi_Logo_bits[] PROGMEM = { 4 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 5 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00, 6 | 0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 7 | 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00, 8 | 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 9 | 0xFF, 0x03, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 10 | 0x00, 0xFF, 0xFF, 0xFF, 0x07, 0xC0, 0x83, 0x01, 0x80, 0xFF, 0xFF, 0xFF, 11 | 0x01, 0x00, 0x07, 0x00, 0xC0, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0C, 0x00, 12 | 0xC0, 0xFF, 0xFF, 0x7C, 0x00, 0x60, 0x0C, 0x00, 0xC0, 0x31, 0x46, 0x7C, 13 | 0xFC, 0x77, 0x08, 0x00, 0xE0, 0x23, 0xC6, 0x3C, 0xFC, 0x67, 0x18, 0x00, 14 | 0xE0, 0x23, 0xE4, 0x3F, 0x1C, 0x00, 0x18, 0x00, 0xE0, 0x23, 0x60, 0x3C, 15 | 0x1C, 0x70, 0x18, 0x00, 0xE0, 0x03, 0x60, 0x3C, 0x1C, 0x70, 0x18, 0x00, 16 | 0xE0, 0x07, 0x60, 0x3C, 0xFC, 0x73, 0x18, 0x00, 0xE0, 0x87, 0x70, 0x3C, 17 | 0xFC, 0x73, 0x18, 0x00, 0xE0, 0x87, 0x70, 0x3C, 0x1C, 0x70, 0x18, 0x00, 18 | 0xE0, 0x87, 0x70, 0x3C, 0x1C, 0x70, 0x18, 0x00, 0xE0, 0x8F, 0x71, 0x3C, 19 | 0x1C, 0x70, 0x18, 0x00, 0xC0, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x08, 0x00, 20 | 0xC0, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x0C, 0x00, 0x80, 0xFF, 0xFF, 0x1F, 21 | 0x00, 0x00, 0x06, 0x00, 0x80, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x07, 0x00, 22 | 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 23 | 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x00, 24 | 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 25 | 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 26 | 0x00, 0x00, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 27 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 28 | }; 29 | -------------------------------------------------------------------------------- /lib/LMIC-Arduino_ID852/src/lmic/hal.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014-2015 IBM Corporation. 3 | * All rights reserved. This program and the accompanying materials 4 | * are made available under the terms of the Eclipse Public License v1.0 5 | * which accompanies this distribution, and is available at 6 | * http://www.eclipse.org/legal/epl-v10.html 7 | * 8 | * Contributors: 9 | * IBM Zurich Research Lab - initial API, implementation and documentation 10 | *******************************************************************************/ 11 | 12 | #ifndef _hal_hpp_ 13 | #define _hal_hpp_ 14 | 15 | #ifdef __cplusplus 16 | extern "C"{ 17 | #endif 18 | 19 | /* 20 | * initialize hardware (IO, SPI, TIMER, IRQ). 21 | */ 22 | void hal_init (void); 23 | 24 | /* 25 | * drive radio NSS pin (0=low, 1=high). 26 | */ 27 | void hal_pin_nss (u1_t val); 28 | 29 | /* 30 | * drive radio RX/TX pins (0=rx, 1=tx). 31 | */ 32 | void hal_pin_rxtx (u1_t val); 33 | 34 | /* 35 | * control radio RST pin (0=low, 1=high, 2=floating) 36 | */ 37 | void hal_pin_rst (u1_t val); 38 | 39 | /* 40 | * perform 8-bit SPI transaction with radio. 41 | * - write given byte 'outval' 42 | * - read byte and return value 43 | */ 44 | u1_t hal_spi (u1_t outval); 45 | 46 | /* 47 | * disable all CPU interrupts. 48 | * - might be invoked nested 49 | * - will be followed by matching call to hal_enableIRQs() 50 | */ 51 | void hal_disableIRQs (void); 52 | 53 | /* 54 | * enable CPU interrupts. 55 | */ 56 | void hal_enableIRQs (void); 57 | 58 | /* 59 | * put system and CPU in low-power mode, sleep until interrupt. 60 | */ 61 | void hal_sleep (void); 62 | 63 | /* 64 | * return 32-bit system time in ticks. 65 | */ 66 | u4_t hal_ticks (void); 67 | 68 | /* 69 | * busy-wait until specified timestamp (in ticks) is reached. 70 | */ 71 | void hal_waitUntil (u4_t time); 72 | 73 | /* 74 | * check and rewind timer for target time. 75 | * - return 1 if target time is close 76 | * - otherwise rewind timer for target time or full period and return 0 77 | */ 78 | u1_t hal_checkTimer (u4_t targettime); 79 | 80 | /* 81 | * perform fatal failure action. 82 | * - called by assertions 83 | * - action could be HALT or reboot 84 | */ 85 | void hal_failed (const char *file, u2_t line); 86 | 87 | #ifdef __cplusplus 88 | } // extern "C" 89 | #endif 90 | 91 | #endif // _hal_hpp_ 92 | -------------------------------------------------------------------------------- /lib/ESP8266_SSD1306_ID562/examples/SSD1306UiDemo/images.h: -------------------------------------------------------------------------------- 1 | #define WiFi_Logo_width 60 2 | #define WiFi_Logo_height 36 3 | const uint8_t WiFi_Logo_bits[] PROGMEM = { 4 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 5 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00, 6 | 0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 7 | 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00, 8 | 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 9 | 0xFF, 0x03, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 10 | 0x00, 0xFF, 0xFF, 0xFF, 0x07, 0xC0, 0x83, 0x01, 0x80, 0xFF, 0xFF, 0xFF, 11 | 0x01, 0x00, 0x07, 0x00, 0xC0, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0C, 0x00, 12 | 0xC0, 0xFF, 0xFF, 0x7C, 0x00, 0x60, 0x0C, 0x00, 0xC0, 0x31, 0x46, 0x7C, 13 | 0xFC, 0x77, 0x08, 0x00, 0xE0, 0x23, 0xC6, 0x3C, 0xFC, 0x67, 0x18, 0x00, 14 | 0xE0, 0x23, 0xE4, 0x3F, 0x1C, 0x00, 0x18, 0x00, 0xE0, 0x23, 0x60, 0x3C, 15 | 0x1C, 0x70, 0x18, 0x00, 0xE0, 0x03, 0x60, 0x3C, 0x1C, 0x70, 0x18, 0x00, 16 | 0xE0, 0x07, 0x60, 0x3C, 0xFC, 0x73, 0x18, 0x00, 0xE0, 0x87, 0x70, 0x3C, 17 | 0xFC, 0x73, 0x18, 0x00, 0xE0, 0x87, 0x70, 0x3C, 0x1C, 0x70, 0x18, 0x00, 18 | 0xE0, 0x87, 0x70, 0x3C, 0x1C, 0x70, 0x18, 0x00, 0xE0, 0x8F, 0x71, 0x3C, 19 | 0x1C, 0x70, 0x18, 0x00, 0xC0, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x08, 0x00, 20 | 0xC0, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x0C, 0x00, 0x80, 0xFF, 0xFF, 0x1F, 21 | 0x00, 0x00, 0x06, 0x00, 0x80, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x07, 0x00, 22 | 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 23 | 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x00, 24 | 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 25 | 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 26 | 0x00, 0x00, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 27 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 28 | }; 29 | 30 | const uint8_t activeSymbol[] PROGMEM = { 31 | B00000000, 32 | B00000000, 33 | B00011000, 34 | B00100100, 35 | B01000010, 36 | B01000010, 37 | B00100100, 38 | B00011000 39 | }; 40 | 41 | const uint8_t inactiveSymbol[] PROGMEM = { 42 | B00000000, 43 | B00000000, 44 | B00000000, 45 | B00000000, 46 | B00011000, 47 | B00011000, 48 | B00000000, 49 | B00000000 50 | }; 51 | -------------------------------------------------------------------------------- /src/config.cpp: -------------------------------------------------------------------------------- 1 | #include "config.h" 2 | 3 | bool loadConfig(int* conf_b, int* conf_r, int* conf_w, int* conf_f) { 4 | File configFile = SPIFFS.open("/config.json", "r"); 5 | 6 | if (!configFile) { 7 | Serial.println("Failed to open config file"); 8 | defaultConfig(); 9 | return false; 10 | } 11 | 12 | size_t size = configFile.size(); 13 | if (size > 1024) { 14 | Serial.println("Config file size is too large"); 15 | return false; 16 | } 17 | 18 | // Allocate a buffer to store contents of the file. 19 | std::unique_ptr buf(new char[size]); 20 | 21 | // We don't use String here because ArduinoJson library requires the input 22 | // buffer to be mutable. If you don't use ArduinoJson, you may as well 23 | // use configFile.readString instead. 24 | configFile.readBytes(buf.get(), size); 25 | 26 | StaticJsonBuffer<200> jsonBuffer; 27 | JsonObject& json = jsonBuffer.parseObject(buf.get()); 28 | 29 | if (!json.success()) { 30 | Serial.println("Failed to parse config file"); 31 | return false; 32 | } 33 | 34 | *conf_b = atoi(json["conf_b"]); 35 | *conf_r = atoi(json["conf_r"]); 36 | *conf_w = atoi(json["conf_w"]); 37 | *conf_f = atoi(json["conf_f"]); 38 | 39 | return true; 40 | } 41 | 42 | bool saveConfig(int conf_b, int conf_r, int conf_w, int conf_f) { 43 | StaticJsonBuffer<200> jsonBuffer; 44 | JsonObject& json = jsonBuffer.createObject(); 45 | char conf_b_str[4]; 46 | sprintf(conf_b_str, "%d", conf_b); 47 | char conf_r_str[4]; 48 | sprintf(conf_r_str, "%d", conf_r); 49 | char conf_w_str[4]; 50 | sprintf(conf_w_str, "%d", conf_w); 51 | char conf_f_str[4]; 52 | sprintf(conf_f_str, "%d", conf_f); 53 | json["conf_b"] = conf_b_str; 54 | json["conf_r"] = conf_r_str; 55 | json["conf_w"] = conf_w_str; 56 | json["conf_f"] = conf_f_str; 57 | 58 | File configFile = SPIFFS.open("/config.json", "w"); 59 | if (!configFile) { 60 | Serial.println("Failed to open config file for writing"); 61 | return false; 62 | } 63 | 64 | json.printTo(configFile); 65 | return true; 66 | } 67 | 68 | bool defaultConfig() { 69 | StaticJsonBuffer<200> jsonBuffer; 70 | JsonObject& json = jsonBuffer.createObject(); 71 | json["conf_b"] = "100"; 72 | json["conf_r"] = "0"; 73 | json["conf_w"] = "0"; 74 | json["conf_f"] = "7"; 75 | 76 | File configFile = SPIFFS.open("/config.json", "w"); 77 | if (!configFile) { 78 | Serial.println("Failed to open config file for writing"); 79 | return false; 80 | } 81 | 82 | json.printTo(configFile); 83 | return true; 84 | } 85 | -------------------------------------------------------------------------------- /python_receiver/receiver.py: -------------------------------------------------------------------------------- 1 | import configparser 2 | import time 3 | import ttn 4 | import base64 5 | import threading 6 | 7 | configFile="caster.conf" 8 | 9 | config = configparser.RawConfigParser() 10 | config.read(configFile) 11 | app_id = config.get('TTN', 'app_id') 12 | access_key = config.get('TTN', 'access_key') 13 | 14 | messages = {} 15 | 16 | lock = threading.Lock() 17 | 18 | def uplink_callback(msg, client): 19 | lock.acquire() 20 | try: 21 | payload_plain = base64.b64decode(msg.payload_raw) 22 | 23 | dev_id = msg.dev_id 24 | prefix = payload_plain[0:3] 25 | message_id = payload_plain[4:6].hex() 26 | message_tot = payload_plain[7:8].hex() 27 | message_no = payload_plain[8:9].hex() 28 | payload = payload_plain[10:].hex() 29 | 30 | if dev_id in messages.keys(): 31 | if message_id in messages[dev_id].keys(): 32 | if message_no in messages[dev_id][message_id].keys(): 33 | #duplicate 34 | print("duplicate") 35 | else: 36 | messages[dev_id][message_id][message_no] = {} 37 | messages[dev_id][message_id][message_no]['payload'] = payload 38 | else: 39 | messages[dev_id][message_id] = {} 40 | messages[dev_id][message_id]['message_tot'] = message_tot 41 | messages[dev_id][message_id][message_no] = {} 42 | messages[dev_id][message_id][message_no]['payload'] = payload 43 | else: 44 | messages[dev_id] = {} 45 | messages[dev_id][message_id] = {} 46 | messages[dev_id][message_id]['message_tot'] = message_tot 47 | messages[dev_id][message_id][message_no] = {} 48 | messages[dev_id][message_id][message_no]['payload'] = payload 49 | finally: 50 | lock.release() 51 | 52 | handler = ttn.HandlerClient(app_id, access_key) 53 | 54 | mqtt_client = handler.data() 55 | mqtt_client.set_uplink_callback(uplink_callback) 56 | mqtt_client.connect() 57 | 58 | while(True): 59 | lock.acquire() 60 | try: 61 | for dev_id in list(messages): 62 | for message_id in list(messages[dev_id]): 63 | buff="" 64 | message_complete=True 65 | for i in range(int(messages[dev_id][message_id]['message_tot'])+1): 66 | try: 67 | buff += messages[dev_id][message_id][format(i, '02x')]['payload'] 68 | except: 69 | message_complete=False 70 | if (message_complete): 71 | #print(messages[dev_id]) 72 | messages[dev_id].pop(message_id) 73 | #print(messages[dev_id]) 74 | print(buff) 75 | finally: 76 | lock.release() 77 | time.sleep(1) 78 | 79 | mqtt_client.close() 80 | -------------------------------------------------------------------------------- /lib/ESP8266_SSD1306_ID562/examples/SSD1306TwoScreenDemo/SSD1306TwoScreenDemo.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2018 by ThingPulse, Daniel Eichhorn 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | * 24 | * ThingPulse invests considerable time and money to develop these open source libraries. 25 | * Please support us by buying our products (and not the clones) from 26 | * https://thingpulse.com 27 | * 28 | */ 29 | 30 | // Include the correct display library 31 | // For a connection via I2C using Wire include 32 | #include // Only needed for Arduino 1.6.5 and earlier 33 | #include "SSD1306.h" // alias for `#include "SSD1306Wire.h"` 34 | #include "images.h" 35 | 36 | // Initialize the OLED display using Wire library 37 | SSD1306 display(0x3c, D3, D5); 38 | SSD1306 display2(0x3c, D1, D2); 39 | 40 | void setup() { 41 | Serial.begin(115200); 42 | Serial.println(); 43 | Serial.println(); 44 | 45 | 46 | // Initialising the UI will init the display too. 47 | display.init(); 48 | display2.init(); 49 | 50 | // This will make sure that multiple instances of a display driver 51 | // running on different ports will work together transparently 52 | display.setI2cAutoInit(true); 53 | display2.setI2cAutoInit(true); 54 | 55 | display.flipScreenVertically(); 56 | display.setFont(ArialMT_Plain_10); 57 | display.setTextAlignment(TEXT_ALIGN_LEFT); 58 | 59 | display2.flipScreenVertically(); 60 | display2.setFont(ArialMT_Plain_10); 61 | display2.setTextAlignment(TEXT_ALIGN_LEFT); 62 | 63 | 64 | 65 | 66 | } 67 | 68 | void loop() { 69 | display.clear(); 70 | display.drawString(0, 0, "Hello world: " + String(millis())); 71 | display.display(); 72 | 73 | display2.clear(); 74 | display2.drawString(0, 0, "Hello world: " + String(millis())); 75 | display2.display(); 76 | 77 | delay(10); 78 | } 79 | -------------------------------------------------------------------------------- /usage_examples/File/receive.py: -------------------------------------------------------------------------------- 1 | import configparser 2 | import sys 3 | import configparser 4 | import time 5 | import ttn 6 | import base64 7 | import threading 8 | 9 | configFile="caster.conf" 10 | 11 | config = configparser.RawConfigParser() 12 | config.read(configFile) 13 | app_id = config.get('TTN', 'app_id') 14 | access_key = config.get('TTN', 'access_key') 15 | 16 | messages = {} 17 | 18 | lock = threading.Lock() 19 | 20 | def uplink_callback(msg, client): 21 | lock.acquire() 22 | try: 23 | payload_plain = base64.b64decode(msg.payload_raw) 24 | 25 | dev_id = msg.dev_id 26 | prefix = payload_plain[0:3] 27 | message_id = payload_plain[4:6].hex() 28 | message_tot = payload_plain[7:8].hex() 29 | message_no = payload_plain[8:9].hex() 30 | payload = payload_plain[10:].hex() 31 | 32 | if dev_id in messages.keys(): 33 | if message_id in messages[dev_id].keys(): 34 | if message_no in messages[dev_id][message_id].keys(): 35 | #duplicate 36 | print("duplicate") 37 | else: 38 | messages[dev_id][message_id][message_no] = {} 39 | messages[dev_id][message_id][message_no]['payload'] = payload 40 | else: 41 | messages[dev_id][message_id] = {} 42 | messages[dev_id][message_id]['message_tot'] = message_tot 43 | messages[dev_id][message_id][message_no] = {} 44 | messages[dev_id][message_id][message_no]['payload'] = payload 45 | else: 46 | messages[dev_id] = {} 47 | messages[dev_id][message_id] = {} 48 | messages[dev_id][message_id]['message_tot'] = message_tot 49 | messages[dev_id][message_id][message_no] = {} 50 | messages[dev_id][message_id][message_no]['payload'] = payload 51 | finally: 52 | lock.release() 53 | 54 | handler = ttn.HandlerClient(app_id, access_key) 55 | 56 | mqtt_client = handler.data() 57 | mqtt_client.set_uplink_callback(uplink_callback) 58 | mqtt_client.connect() 59 | 60 | while(True): 61 | lock.acquire() 62 | try: 63 | for dev_id in list(messages): 64 | for message_id in list(messages[dev_id]): 65 | buff="" 66 | message_complete=True 67 | for i in range(int(messages[dev_id][message_id]['message_tot'])+1): 68 | try: 69 | buff += messages[dev_id][message_id][format(i, '02x')]['payload'] 70 | except: 71 | message_complete=False 72 | if (message_complete): 73 | #print(messages[dev_id]) 74 | messages[dev_id].pop(message_id) 75 | #print(messages[dev_id]) 76 | print(buff) 77 | file = open('received.txt','w') 78 | file.write(bytearray.fromhex(buff).decode('utf-8')) 79 | file.close() 80 | finally: 81 | lock.release() 82 | time.sleep(10) 83 | 84 | mqtt_client.close() 85 | -------------------------------------------------------------------------------- /usage_examples/BTC/receive.py: -------------------------------------------------------------------------------- 1 | import configparser 2 | from bitcoin_rpc_class import RPCHost 3 | import sys 4 | import configparser 5 | import time 6 | import ttn 7 | import base64 8 | import threading 9 | 10 | configFile="caster.conf" 11 | 12 | config = configparser.RawConfigParser() 13 | config.read(configFile) 14 | app_id = config.get('TTN', 'app_id') 15 | access_key = config.get('TTN', 'access_key') 16 | rpcHost = config.get('BTC', 'host') 17 | rpcPort = config.get('BTC', 'port') 18 | rpcUser = config.get('BTC', 'username') 19 | rpcPassword = config.get('BTC', 'password') 20 | address = config.get('BTC', 'address') 21 | rpcWallet = config.get('BTC', 'wallet') 22 | serverURL = 'http://' + rpcUser + ':' + rpcPassword + '@'+rpcHost+':' + str(rpcPort)+'/wallet/' + rpcWallet 23 | #serverURL = 'http://' + rpcUser + ':' + rpcPassword + '@'+rpcHost+':' + str(rpcPort) 24 | 25 | host = RPCHost(serverURL) 26 | 27 | messages = {} 28 | 29 | lock = threading.Lock() 30 | 31 | def uplink_callback(msg, client): 32 | lock.acquire() 33 | try: 34 | payload_plain = base64.b64decode(msg.payload_raw) 35 | 36 | dev_id = msg.dev_id 37 | prefix = payload_plain[0:3] 38 | message_id = payload_plain[4:6].hex() 39 | message_tot = payload_plain[7:8].hex() 40 | message_no = payload_plain[8:9].hex() 41 | payload = payload_plain[10:].hex() 42 | 43 | if dev_id in messages.keys(): 44 | if message_id in messages[dev_id].keys(): 45 | if message_no in messages[dev_id][message_id].keys(): 46 | #duplicate 47 | print("duplicate") 48 | else: 49 | messages[dev_id][message_id][message_no] = {} 50 | messages[dev_id][message_id][message_no]['payload'] = payload 51 | else: 52 | messages[dev_id][message_id] = {} 53 | messages[dev_id][message_id]['message_tot'] = message_tot 54 | messages[dev_id][message_id][message_no] = {} 55 | messages[dev_id][message_id][message_no]['payload'] = payload 56 | else: 57 | messages[dev_id] = {} 58 | messages[dev_id][message_id] = {} 59 | messages[dev_id][message_id]['message_tot'] = message_tot 60 | messages[dev_id][message_id][message_no] = {} 61 | messages[dev_id][message_id][message_no]['payload'] = payload 62 | finally: 63 | lock.release() 64 | 65 | handler = ttn.HandlerClient(app_id, access_key) 66 | 67 | mqtt_client = handler.data() 68 | mqtt_client.set_uplink_callback(uplink_callback) 69 | mqtt_client.connect() 70 | 71 | while(True): 72 | lock.acquire() 73 | try: 74 | for dev_id in list(messages): 75 | for message_id in list(messages[dev_id]): 76 | buff="" 77 | message_complete=True 78 | for i in range(int(messages[dev_id][message_id]['message_tot'])+1): 79 | try: 80 | buff += messages[dev_id][message_id][format(i, '02x')]['payload'] 81 | except: 82 | message_complete=False 83 | if (message_complete): 84 | #print(messages[dev_id]) 85 | messages[dev_id].pop(message_id) 86 | #print(messages[dev_id]) 87 | print(buff) 88 | tx = buff.strip() 89 | print(tx) 90 | res = host.call('decoderawtransaction', tx, True) 91 | print(res) 92 | res = host.call('sendrawtransaction', tx) 93 | print(res) 94 | finally: 95 | lock.release() 96 | time.sleep(10) 97 | 98 | mqtt_client.close() 99 | -------------------------------------------------------------------------------- /usage_examples/LTC/receive.py: -------------------------------------------------------------------------------- 1 | import configparser 2 | from bitcoin_rpc_class import RPCHost 3 | import sys 4 | import configparser 5 | import time 6 | import ttn 7 | import base64 8 | import threading 9 | 10 | configFile="caster.conf" 11 | 12 | config = configparser.RawConfigParser() 13 | config.read(configFile) 14 | app_id = config.get('TTN', 'app_id') 15 | access_key = config.get('TTN', 'access_key') 16 | rpcHost = config.get('LTC', 'host') 17 | rpcPort = config.get('LTC', 'port') 18 | rpcUser = config.get('LTC', 'username') 19 | rpcPassword = config.get('LTC', 'password') 20 | address = config.get('LTC', 'address') 21 | rpcWallet = config.get('LTC', 'wallet') 22 | serverURL = 'http://' + rpcUser + ':' + rpcPassword + '@'+rpcHost+':' + str(rpcPort)+'/wallet/' + rpcWallet 23 | #serverURL = 'http://' + rpcUser + ':' + rpcPassword + '@'+rpcHost+':' + str(rpcPort) 24 | 25 | host = RPCHost(serverURL) 26 | 27 | messages = {} 28 | 29 | lock = threading.Lock() 30 | 31 | def uplink_callback(msg, client): 32 | lock.acquire() 33 | try: 34 | payload_plain = base64.b64decode(msg.payload_raw) 35 | 36 | dev_id = msg.dev_id 37 | prefix = payload_plain[0:3] 38 | message_id = payload_plain[4:6].hex() 39 | message_tot = payload_plain[7:8].hex() 40 | message_no = payload_plain[8:9].hex() 41 | payload = payload_plain[10:].hex() 42 | 43 | if dev_id in messages.keys(): 44 | if message_id in messages[dev_id].keys(): 45 | if message_no in messages[dev_id][message_id].keys(): 46 | #duplicate 47 | print("duplicate") 48 | else: 49 | messages[dev_id][message_id][message_no] = {} 50 | messages[dev_id][message_id][message_no]['payload'] = payload 51 | else: 52 | messages[dev_id][message_id] = {} 53 | messages[dev_id][message_id]['message_tot'] = message_tot 54 | messages[dev_id][message_id][message_no] = {} 55 | messages[dev_id][message_id][message_no]['payload'] = payload 56 | else: 57 | messages[dev_id] = {} 58 | messages[dev_id][message_id] = {} 59 | messages[dev_id][message_id]['message_tot'] = message_tot 60 | messages[dev_id][message_id][message_no] = {} 61 | messages[dev_id][message_id][message_no]['payload'] = payload 62 | finally: 63 | lock.release() 64 | 65 | handler = ttn.HandlerClient(app_id, access_key) 66 | 67 | mqtt_client = handler.data() 68 | mqtt_client.set_uplink_callback(uplink_callback) 69 | mqtt_client.connect() 70 | 71 | while(True): 72 | lock.acquire() 73 | try: 74 | for dev_id in list(messages): 75 | for message_id in list(messages[dev_id]): 76 | buff="" 77 | message_complete=True 78 | for i in range(int(messages[dev_id][message_id]['message_tot'])+1): 79 | try: 80 | buff += messages[dev_id][message_id][format(i, '02x')]['payload'] 81 | except: 82 | message_complete=False 83 | if (message_complete): 84 | #print(messages[dev_id]) 85 | messages[dev_id].pop(message_id) 86 | #print(messages[dev_id]) 87 | print(buff) 88 | tx = buff.strip() 89 | print(tx) 90 | res = host.call('decoderawtransaction', tx, True) 91 | print(res) 92 | res = host.call('sendrawtransaction', tx) 93 | print(res) 94 | finally: 95 | lock.release() 96 | time.sleep(10) 97 | 98 | mqtt_client.close() 99 | -------------------------------------------------------------------------------- /lib/LMIC-Arduino_ID852/src/lmic/config.h: -------------------------------------------------------------------------------- 1 | #ifndef _lmic_config_h_ 2 | #define _lmic_config_h_ 3 | 4 | // In the original LMIC code, these config values were defined on the 5 | // gcc commandline. Since Arduino does not allow easily modifying the 6 | // compiler commandline, use this file instead. 7 | 8 | #define CFG_eu868 1 9 | //#define CFG_us915 1 10 | // This is the SX1272/SX1273 radio, which is also used on the HopeRF 11 | // RFM92 boards. 12 | //#define CFG_sx1272_radio 1 13 | // This is the SX1276/SX1277/SX1278/SX1279 radio, which is also used on 14 | // the HopeRF RFM95 boards. 15 | #define CFG_sx1276_radio 1 16 | 17 | // 16 μs per tick 18 | // LMIC requires ticks to be 15.5μs - 100 μs long 19 | #define US_PER_OSTICK_EXPONENT 4 20 | #define US_PER_OSTICK (1 << US_PER_OSTICK_EXPONENT) 21 | #define OSTICKS_PER_SEC (1000000 / US_PER_OSTICK) 22 | 23 | // Set this to 1 to enable some basic debug output (using printf) about 24 | // RF settings used during transmission and reception. Set to 2 to 25 | // enable more verbose output. Make sure that printf is actually 26 | // configured (e.g. on AVR it is not by default), otherwise using it can 27 | // cause crashing. 28 | #define LMIC_DEBUG_LEVEL 0 29 | 30 | // Enable this to allow using printf() to print to the given serial port 31 | // (or any other Print object). This can be easy for debugging. The 32 | // current implementation only works on AVR, though. 33 | //#define LMIC_PRINTF_TO Serial 34 | 35 | // Any runtime assertion failures are printed to this serial port (or 36 | // any other Print object). If this is unset, any failures just silently 37 | // halt execution. 38 | #define LMIC_FAILURE_TO Serial 39 | 40 | // Uncomment this to disable all code related to joining 41 | //#define DISABLE_JOIN 42 | // Uncomment this to disable all code related to ping 43 | //#define DISABLE_PING 44 | // Uncomment this to disable all code related to beacon tracking. 45 | // Requires ping to be disabled too 46 | //#define DISABLE_BEACONS 47 | 48 | // Uncomment these to disable the corresponding MAC commands. 49 | // Class A 50 | //#define DISABLE_MCMD_DCAP_REQ // duty cycle cap 51 | //#define DISABLE_MCMD_DN2P_SET // 2nd DN window param 52 | //#define DISABLE_MCMD_SNCH_REQ // set new channel 53 | // Class B 54 | //#define DISABLE_MCMD_PING_SET // set ping freq, automatically disabled by DISABLE_PING 55 | //#define DISABLE_MCMD_BCNI_ANS // next beacon start, automatical disabled by DISABLE_BEACON 56 | 57 | // In LoRaWAN, a gateway applies I/Q inversion on TX, and nodes do the 58 | // same on RX. This ensures that gateways can talk to nodes and vice 59 | // versa, but gateways will not hear other gateways and nodes will not 60 | // hear other nodes. By uncommenting this macro, this inversion is 61 | // disabled and this node can hear other nodes. If two nodes both have 62 | // this macro set, they can talk to each other (but they can no longer 63 | // hear gateways). This should probably only be used when debugging 64 | // and/or when talking to the radio directly (e.g. like in the "raw" 65 | // example). 66 | //#define DISABLE_INVERT_IQ_ON_RX 67 | 68 | // This allows choosing between multiple included AES implementations. 69 | // Make sure exactly one of these is uncommented. 70 | // 71 | // This selects the original AES implementation included LMIC. This 72 | // implementation is optimized for speed on 32-bit processors using 73 | // fairly big lookup tables, but it takes up big amounts of flash on the 74 | // AVR architecture. 75 | // #define USE_ORIGINAL_AES 76 | // 77 | // This selects the AES implementation written by Ideetroon for their 78 | // own LoRaWAN library. It also uses lookup tables, but smaller 79 | // byte-oriented ones, making it use a lot less flash space (but it is 80 | // also about twice as slow as the original). 81 | #define USE_IDEETRON_AES 82 | 83 | #endif // _lmic_config_h_ 84 | -------------------------------------------------------------------------------- /lib/LMIC-Arduino_ID852/src/lmic/oslmic.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014-2015 IBM Corporation. 3 | * All rights reserved. This program and the accompanying materials 4 | * are made available under the terms of the Eclipse Public License v1.0 5 | * which accompanies this distribution, and is available at 6 | * http://www.eclipse.org/legal/epl-v10.html 7 | * 8 | * Contributors: 9 | * IBM Zurich Research Lab - initial API, implementation and documentation 10 | *******************************************************************************/ 11 | 12 | #include "lmic.h" 13 | #include 14 | 15 | // RUNTIME STATE 16 | static struct { 17 | osjob_t* scheduledjobs; 18 | osjob_t* runnablejobs; 19 | } OS; 20 | 21 | void os_init () { 22 | memset(&OS, 0x00, sizeof(OS)); 23 | hal_init(); 24 | radio_init(); 25 | LMIC_init(); 26 | } 27 | 28 | ostime_t os_getTime () { 29 | return hal_ticks(); 30 | } 31 | 32 | static u1_t unlinkjob (osjob_t** pnext, osjob_t* job) { 33 | for( ; *pnext; pnext = &((*pnext)->next)) { 34 | if(*pnext == job) { // unlink 35 | *pnext = job->next; 36 | return 1; 37 | } 38 | } 39 | return 0; 40 | } 41 | 42 | // clear scheduled job 43 | void os_clearCallback (osjob_t* job) { 44 | hal_disableIRQs(); 45 | u1_t res = unlinkjob(&OS.scheduledjobs, job) || unlinkjob(&OS.runnablejobs, job); 46 | hal_enableIRQs(); 47 | #if LMIC_DEBUG_LEVEL > 1 48 | if (res) 49 | lmic_printf("%lu: Cleared job %p\n", os_getTime(), job); 50 | #endif 51 | } 52 | 53 | // schedule immediately runnable job 54 | void os_setCallback (osjob_t* job, osjobcb_t cb) { 55 | osjob_t** pnext; 56 | hal_disableIRQs(); 57 | // remove if job was already queued 58 | os_clearCallback(job); 59 | // fill-in job 60 | job->func = cb; 61 | job->next = NULL; 62 | // add to end of run queue 63 | for(pnext=&OS.runnablejobs; *pnext; pnext=&((*pnext)->next)); 64 | *pnext = job; 65 | hal_enableIRQs(); 66 | #if LMIC_DEBUG_LEVEL > 1 67 | lmic_printf("%lu: Scheduled job %p, cb %p ASAP\n", os_getTime(), job, cb); 68 | #endif 69 | } 70 | 71 | // schedule timed job 72 | void os_setTimedCallback (osjob_t* job, ostime_t time, osjobcb_t cb) { 73 | osjob_t** pnext; 74 | hal_disableIRQs(); 75 | // remove if job was already queued 76 | os_clearCallback(job); 77 | // fill-in job 78 | job->deadline = time; 79 | job->func = cb; 80 | job->next = NULL; 81 | // insert into schedule 82 | for(pnext=&OS.scheduledjobs; *pnext; pnext=&((*pnext)->next)) { 83 | if((*pnext)->deadline - time > 0) { // (cmp diff, not abs!) 84 | // enqueue before next element and stop 85 | job->next = *pnext; 86 | break; 87 | } 88 | } 89 | *pnext = job; 90 | hal_enableIRQs(); 91 | #if LMIC_DEBUG_LEVEL > 1 92 | lmic_printf("%lu: Scheduled job %p, cb %p at %lu\n", os_getTime(), job, cb, time); 93 | #endif 94 | } 95 | 96 | // execute jobs from timer and from run queue 97 | void os_runloop () { 98 | while(1) { 99 | os_runloop_once(); 100 | } 101 | } 102 | 103 | void os_runloop_once() { 104 | #if LMIC_DEBUG_LEVEL > 1 105 | bool has_deadline = false; 106 | #endif 107 | osjob_t* j = NULL; 108 | hal_disableIRQs(); 109 | // check for runnable jobs 110 | if(OS.runnablejobs) { 111 | j = OS.runnablejobs; 112 | OS.runnablejobs = j->next; 113 | } else if(OS.scheduledjobs && hal_checkTimer(OS.scheduledjobs->deadline)) { // check for expired timed jobs 114 | j = OS.scheduledjobs; 115 | OS.scheduledjobs = j->next; 116 | #if LMIC_DEBUG_LEVEL > 1 117 | has_deadline = true; 118 | #endif 119 | } else { // nothing pending 120 | hal_sleep(); // wake by irq (timer already restarted) 121 | } 122 | hal_enableIRQs(); 123 | if(j) { // run job callback 124 | #if LMIC_DEBUG_LEVEL > 1 125 | lmic_printf("%lu: Running job %p, cb %p, deadline %lu\n", os_getTime(), j, j->func, has_deadline ? j->deadline : 0); 126 | #endif 127 | j->func(j); 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /lib/ESP8266_SSD1306_ID562/examples/SSD1306OTADemo/SSD1306OTADemo.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2018 by ThingPulse, Daniel Eichhorn 5 | * Copyright (c) 2018 by Fabrice Weinberg 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | * 25 | * ThingPulse invests considerable time and money to develop these open source libraries. 26 | * Please support us by buying our products (and not the clones) from 27 | * https://thingpulse.com 28 | * 29 | */ 30 | 31 | // WiFi includes 32 | #include 33 | 34 | // OTA Includes 35 | #include 36 | #include 37 | 38 | const char *ssid = "[Your SSID]"; 39 | const char *password = "[Your Password]"; 40 | 41 | 42 | // Include the correct display library 43 | // For a connection via I2C using Wire include 44 | #include // Only needed for Arduino 1.6.5 and earlier 45 | #include "SSD1306.h" // alias for `#include "SSD1306Wire.h"` 46 | // or #include "SH1106.h" alis for `#include "SH1106Wire.h"` 47 | // For a connection via I2C using brzo_i2c (must be installed) include 48 | // #include // Only needed for Arduino 1.6.5 and earlier 49 | // #include "SSD1306Brzo.h" 50 | // #include "SH1106Brzo.h" 51 | // For a connection via SPI include 52 | // #include // Only needed for Arduino 1.6.5 and earlier 53 | // #include "SSD1306Spi.h" 54 | // #include "SH1106SPi.h" 55 | 56 | // Use the corresponding display class: 57 | 58 | // Initialize the OLED display using SPI 59 | // D5 -> CLK 60 | // D7 -> MOSI (DOUT) 61 | // D0 -> RES 62 | // D2 -> DC 63 | // D8 -> CS 64 | // SSD1306Spi display(D0, D2, D8); 65 | // or 66 | // SH1106Spi display(D0, D2); 67 | 68 | // Initialize the OLED display using brzo_i2c 69 | // D3 -> SDA 70 | // D5 -> SCL 71 | // SSD1306Brzo display(0x3c, D3, D5); 72 | // or 73 | // SH1106Brzo display(0x3c, D3, D5); 74 | 75 | // Initialize the OLED display using Wire library 76 | SSD1306 display(0x3c, D3, D5); 77 | // SH1106 display(0x3c, D3, D5); 78 | 79 | 80 | void setup() { 81 | WiFi.begin ( ssid, password ); 82 | 83 | // Wait for connection 84 | while ( WiFi.status() != WL_CONNECTED ) { 85 | delay ( 10 ); 86 | } 87 | 88 | display.init(); 89 | display.flipScreenVertically(); 90 | display.setContrast(255); 91 | 92 | ArduinoOTA.begin(); 93 | ArduinoOTA.onStart([]() { 94 | display.clear(); 95 | display.setFont(ArialMT_Plain_10); 96 | display.setTextAlignment(TEXT_ALIGN_CENTER_BOTH); 97 | display.drawString(display.getWidth()/2, display.getHeight()/2 - 10, "OTA Update"); 98 | display.display(); 99 | }); 100 | 101 | ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { 102 | display.drawProgressBar(4, 32, 120, 8, progress / (total / 100) ); 103 | display.display(); 104 | }); 105 | 106 | ArduinoOTA.onEnd([]() { 107 | display.clear(); 108 | display.setFont(ArialMT_Plain_10); 109 | display.setTextAlignment(TEXT_ALIGN_CENTER_BOTH); 110 | display.drawString(display.getWidth()/2, display.getHeight()/2, "Restart"); 111 | display.display(); 112 | }); 113 | 114 | // Align text vertical/horizontal center 115 | display.setTextAlignment(TEXT_ALIGN_CENTER_BOTH); 116 | display.setFont(ArialMT_Plain_10); 117 | display.drawString(display.getWidth()/2, display.getHeight()/2, "Ready for OTA:\n" + WiFi.localIP().toString()); 118 | display.display(); 119 | } 120 | 121 | void loop() { 122 | ArduinoOTA.handle(); 123 | } 124 | -------------------------------------------------------------------------------- /lib/ESP8266_SSD1306_ID562/SH1106Spi.h: -------------------------------------------------------------------------------- 1 | /** 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2018 by ThingPulse, Daniel Eichhorn 5 | * Copyright (c) 2018 by Fabrice Weinberg 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | * 25 | * ThingPulse invests considerable time and money to develop these open source libraries. 26 | * Please support us by buying our products (and not the clones) from 27 | * https://thingpulse.com 28 | * 29 | */ 30 | 31 | #ifndef SH1106Spi_h 32 | #define SH1106Spi_h 33 | 34 | #include "OLEDDisplay.h" 35 | #include 36 | 37 | class SH1106Spi : public OLEDDisplay { 38 | private: 39 | uint8_t _rst; 40 | uint8_t _dc; 41 | 42 | public: 43 | SH1106Spi(uint8_t _rst, uint8_t _dc, uint8_t _cs, OLEDDISPLAY_GEOMETRY g = GEOMETRY_128_64) { 44 | setGeometry(g); 45 | 46 | this->_rst = _rst; 47 | this->_dc = _dc; 48 | } 49 | 50 | bool connect(){ 51 | pinMode(_dc, OUTPUT); 52 | pinMode(_rst, OUTPUT); 53 | 54 | SPI.begin (); 55 | SPI.setClockDivider (SPI_CLOCK_DIV2); 56 | 57 | // Pulse Reset low for 10ms 58 | digitalWrite(_rst, HIGH); 59 | delay(1); 60 | digitalWrite(_rst, LOW); 61 | delay(10); 62 | digitalWrite(_rst, HIGH); 63 | return true; 64 | } 65 | 66 | void display(void) { 67 | #ifdef OLEDDISPLAY_DOUBLE_BUFFER 68 | uint8_t minBoundY = ~0; 69 | uint8_t maxBoundY = 0; 70 | 71 | uint8_t minBoundX = ~0; 72 | uint8_t maxBoundX = 0; 73 | 74 | uint8_t x, y; 75 | 76 | // Calculate the Y bounding box of changes 77 | // and copy buffer[pos] to buffer_back[pos]; 78 | for (y = 0; y < (displayHeight / 8); y++) { 79 | for (x = 0; x < displayWidth; x++) { 80 | uint16_t pos = x + y * displayWidth; 81 | if (buffer[pos] != buffer_back[pos]) { 82 | minBoundY = _min(minBoundY, y); 83 | maxBoundY = _max(maxBoundY, y); 84 | minBoundX = _min(minBoundX, x); 85 | maxBoundX = _max(maxBoundX, x); 86 | } 87 | buffer_back[pos] = buffer[pos]; 88 | } 89 | yield(); 90 | } 91 | 92 | // If the minBoundY wasn't updated 93 | // we can savely assume that buffer_back[pos] == buffer[pos] 94 | // holdes true for all values of pos 95 | if (minBoundY == ~0) return; 96 | 97 | // Calculate the colum offset 98 | uint8_t minBoundXp2H = (minBoundX + 2) & 0x0F; 99 | uint8_t minBoundXp2L = 0x10 | ((minBoundX + 2) >> 4 ); 100 | 101 | for (y = minBoundY; y <= maxBoundY; y++) { 102 | sendCommand(0xB0 + y); 103 | sendCommand(minBoundXp2H); 104 | sendCommand(minBoundXp2L); 105 | digitalWrite(_dc, HIGH); // data mode 106 | for (x = minBoundX; x <= maxBoundX; x++) { 107 | SPI.transfer(buffer[x + y * displayWidth]); 108 | } 109 | yield(); 110 | } 111 | #else 112 | for (uint8_t y=0; y 36 | 37 | #if F_CPU == 160000000L 38 | #define BRZO_I2C_SPEED 1000 39 | #else 40 | #define BRZO_I2C_SPEED 800 41 | #endif 42 | 43 | class SH1106Brzo : public OLEDDisplay { 44 | private: 45 | uint8_t _address; 46 | uint8_t _sda; 47 | uint8_t _scl; 48 | 49 | public: 50 | SH1106Brzo(uint8_t _address, uint8_t _sda, uint8_t _scl, OLEDDISPLAY_GEOMETRY g = GEOMETRY_128_64) { 51 | setGeometry(g); 52 | 53 | this->_address = _address; 54 | this->_sda = _sda; 55 | this->_scl = _scl; 56 | } 57 | 58 | bool connect(){ 59 | brzo_i2c_setup(_sda, _scl, 0); 60 | return true; 61 | } 62 | 63 | void display(void) { 64 | #ifdef OLEDDISPLAY_DOUBLE_BUFFER 65 | uint8_t minBoundY = ~0; 66 | uint8_t maxBoundY = 0; 67 | 68 | uint8_t minBoundX = ~0; 69 | uint8_t maxBoundX = 0; 70 | uint8_t x, y; 71 | 72 | // Calculate the Y bounding box of changes 73 | // and copy buffer[pos] to buffer_back[pos]; 74 | for (y = 0; y < (displayHeight / 8); y++) { 75 | for (x = 0; x < displayWidth; x++) { 76 | uint16_t pos = x + y * displayWidth; 77 | if (buffer[pos] != buffer_back[pos]) { 78 | minBoundY = _min(minBoundY, y); 79 | maxBoundY = _max(maxBoundY, y); 80 | minBoundX = _min(minBoundX, x); 81 | maxBoundX = _max(maxBoundX, x); 82 | } 83 | buffer_back[pos] = buffer[pos]; 84 | } 85 | yield(); 86 | } 87 | 88 | // If the minBoundY wasn't updated 89 | // we can savely assume that buffer_back[pos] == buffer[pos] 90 | // holdes true for all values of pos 91 | if (minBoundY == ~0) return; 92 | 93 | byte k = 0; 94 | uint8_t sendBuffer[17]; 95 | sendBuffer[0] = 0x40; 96 | 97 | // Calculate the colum offset 98 | uint8_t minBoundXp2H = (minBoundX + 2) & 0x0F; 99 | uint8_t minBoundXp2L = 0x10 | ((minBoundX + 2) >> 4 ); 100 | 101 | brzo_i2c_start_transaction(this->_address, BRZO_I2C_SPEED); 102 | 103 | for (y = minBoundY; y <= maxBoundY; y++) { 104 | sendCommand(0xB0 + y); 105 | sendCommand(minBoundXp2H); 106 | sendCommand(minBoundXp2L); 107 | for (x = minBoundX; x <= maxBoundX; x++) { 108 | k++; 109 | sendBuffer[k] = buffer[x + y * displayWidth]; 110 | if (k == 16) { 111 | brzo_i2c_write(sendBuffer, 17, true); 112 | k = 0; 113 | } 114 | } 115 | if (k != 0) { 116 | brzo_i2c_write(sendBuffer, k + 1, true); 117 | k = 0; 118 | } 119 | yield(); 120 | } 121 | if (k != 0) { 122 | brzo_i2c_write(sendBuffer, k + 1, true); 123 | } 124 | brzo_i2c_end_transaction(); 125 | #else 126 | #endif 127 | } 128 | 129 | private: 130 | inline void sendCommand(uint8_t com) __attribute__((always_inline)){ 131 | uint8_t command[2] = {0x80 /* command mode */, com}; 132 | brzo_i2c_start_transaction(_address, BRZO_I2C_SPEED); 133 | brzo_i2c_write(command, 2, true); 134 | brzo_i2c_end_transaction(); 135 | } 136 | }; 137 | 138 | #endif 139 | -------------------------------------------------------------------------------- /lib/ESP8266_SSD1306_ID562/UPGRADE-3.0.md: -------------------------------------------------------------------------------- 1 | # Upgrade from 2.0 to 3.0 2 | 3 | While developing version 3.0 we made some breaking changes to the public 4 | API of this library. This document will help you update your code to work with 5 | version 3.0 6 | 7 | ## Font Definitions 8 | 9 | To get better performance and a smaller font definition format, we change the memory 10 | layout of the font definition format. If you are using custom fonts not included in 11 | this library we updated the font generator [here](http://oleddisplay.squix.ch/#/home). 12 | Please update your fonts to be working with 3.0 by selecting the respective version in the dropdown. 13 | 14 | 15 | ## Architectural Changes 16 | 17 | To become a more versatile library for the SSD1306 chipset we abstracted the 18 | hardware connection into subclasses of the base display class now called `OLEDDisplay`. 19 | This library is currently shipping with three implementations: 20 | 21 | * `SSD1306Wire` implementing the I2C protocol using the Wire Library. 22 | * `SSD1306Brzo` implementing the I2C protocol using the faster [`brzo_i2c`](https://github.com/pasko-zh/brzo_i2c) library. 23 | * `SSD1306Spi` implementing the SPI protocol. 24 | 25 | To keep backwards compatiblity with the old API `SSD1306` is an alias of `SSD1306Wire`. 26 | If you are not using the UI components you don't have to change anything to keep your code working. 27 | 28 | ## Name Changes 29 | 30 | [Naming things is hard](http://martinfowler.com/bliki/TwoHardThings.html), to better reflect our intention with this library 31 | we changed the name of the base class to `OLEDDisplay` and the UI library accordingly to `OLEDDisplayUi`. 32 | As a consequence the type definitions of all frame and overlay related functions changed. 33 | This means that you have to update all your frame drawing callbacks from: 34 | 35 | ```c 36 | bool frame1(SSD1306 *display, SSD1306UiState* state, int x, int y); 37 | ``` 38 | 39 | too 40 | 41 | ```c 42 | void frame1(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y); 43 | ``` 44 | 45 | And your overlay drawing functions from: 46 | 47 | ```c 48 | bool overlay1(SSD1306 *display, SSD1306UiState* state); 49 | ``` 50 | 51 | too 52 | 53 | ```c 54 | void overlay1(OLEDDisplay *display, OLEDDisplayUiState* state); 55 | ``` 56 | 57 | ## New Features 58 | 59 | ### Loading Animation 60 | 61 | While using this library ourself we noticed a pattern emerging. We want to drawing 62 | a loading progress while connecting to WiFi and updating weather data etc. 63 | 64 | The simplest thing was to add the function `drawProgressBar(x, y, width, height, progress)` 65 | ,where `progress` is between `0` and `100`, right to the `OLEDDisplay` class. 66 | 67 | But we didn't stop there. We added a new feature to the `OLEDDisplayUi` called `LoadingStages`. 68 | You can define your loading process like this: 69 | 70 | ```c++ 71 | LoadingStage loadingStages[] = { 72 | { 73 | .process = "Connect to WiFi", 74 | .callback = []() { 75 | // Connect to WiFi 76 | } 77 | }, 78 | { 79 | .process = "Get time from NTP", 80 | .callback = []() { 81 | // Get current time via NTP 82 | } 83 | } 84 | // more steps 85 | }; 86 | 87 | int LOADING_STAGES_COUNT = sizeof(loadingStages) / sizeof(LoadingStage); 88 | ``` 89 | 90 | After defining your array of `LoadingStages` you can then run the loading process by using 91 | `ui.runLoadingProcess(loadingStages, LOADING_STAGES_COUNT)`. This will give you a 92 | nice little loading animation you can see in the beginning of [this](https://vimeo.com/168362918) 93 | video. 94 | 95 | To further customize this you are free to define your own `LoadingDrawFunction` like this: 96 | 97 | ```c 98 | void myLoadingDraw(OLEDDisplay *display, LoadingStage* stage, uint8_t progress) { 99 | display->setTextAlignment(TEXT_ALIGN_CENTER); 100 | display->setFont(ArialMT_Plain_10); 101 | // stage->process contains the text of the current progress e.q. "Connect to WiFi" 102 | display->drawString(64, 18, stage->process); 103 | // you could just print the current process without the progress bar 104 | display->drawString(64, 28, progress); 105 | } 106 | ``` 107 | 108 | After defining a function like that, you can pass it to the Ui library by use 109 | `ui.setLoadingDrawFunction(myLoadingDraw)`. 110 | 111 | 112 | ### Text Logging 113 | 114 | It is always useful to display some text on the display without worrying to much 115 | where it goes and managing it. In 3.0 we made the `OLEDDisplay` class implement 116 | [`Print`](https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/cores/arduino/Print.h) 117 | so you can use it like you would use `Serial`. We calls this feature `LogBuffer` 118 | and the only thing you have to do is to define how many lines you want to display 119 | and how many characters there are on average on each. This is done by calling 120 | `setLogBuffer(lines, chars);`. If there is not enough memory the function will 121 | return false. 122 | 123 | After that you can draw the `LogBuffer` anywhere you want by calling `drawLogBuffer(x, y)`. 124 | (Note: You have to call `display()` to update the screen) 125 | We made a [video](https://www.youtube.com/watch?v=8Fiss77A3TE) showing this feature in action. 126 | -------------------------------------------------------------------------------- /lib/ESP8266_SSD1306_ID562/SSD1306Spi.h: -------------------------------------------------------------------------------- 1 | /** 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2018 by ThingPulse, Daniel Eichhorn 5 | * Copyright (c) 2018 by Fabrice Weinberg 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | * 25 | * ThingPulse invests considerable time and money to develop these open source libraries. 26 | * Please support us by buying our products (and not the clones) from 27 | * https://thingpulse.com 28 | * 29 | */ 30 | 31 | #ifndef SSD1306Spi_h 32 | #define SSD1306Spi_h 33 | 34 | #include "OLEDDisplay.h" 35 | #include 36 | 37 | #if F_CPU == 160000000L 38 | #define BRZO_I2C_SPEED 1000 39 | #else 40 | #define BRZO_I2C_SPEED 800 41 | #endif 42 | 43 | class SSD1306Spi : public OLEDDisplay { 44 | private: 45 | uint8_t _rst; 46 | uint8_t _dc; 47 | uint8_t _cs; 48 | 49 | public: 50 | SSD1306Spi(uint8_t _rst, uint8_t _dc, uint8_t _cs, OLEDDISPLAY_GEOMETRY g = GEOMETRY_128_64) { 51 | setGeometry(g); 52 | 53 | this->_rst = _rst; 54 | this->_dc = _dc; 55 | this->_cs = _cs; 56 | } 57 | 58 | bool connect(){ 59 | pinMode(_dc, OUTPUT); 60 | pinMode(_cs, OUTPUT); 61 | pinMode(_rst, OUTPUT); 62 | 63 | SPI.begin (); 64 | SPI.setClockDivider (SPI_CLOCK_DIV2); 65 | 66 | // Pulse Reset low for 10ms 67 | digitalWrite(_rst, HIGH); 68 | delay(1); 69 | digitalWrite(_rst, LOW); 70 | delay(10); 71 | digitalWrite(_rst, HIGH); 72 | return true; 73 | } 74 | 75 | void display(void) { 76 | #ifdef OLEDDISPLAY_DOUBLE_BUFFER 77 | uint8_t minBoundY = ~0; 78 | uint8_t maxBoundY = 0; 79 | 80 | uint8_t minBoundX = ~0; 81 | uint8_t maxBoundX = 0; 82 | 83 | uint8_t x, y; 84 | 85 | // Calculate the Y bounding box of changes 86 | // and copy buffer[pos] to buffer_back[pos]; 87 | for (y = 0; y < (displayHeight / 8); y++) { 88 | for (x = 0; x < displayWidth; x++) { 89 | uint16_t pos = x + y * displayWidth; 90 | if (buffer[pos] != buffer_back[pos]) { 91 | minBoundY = _min(minBoundY, y); 92 | maxBoundY = _max(maxBoundY, y); 93 | minBoundX = _min(minBoundX, x); 94 | maxBoundX = _max(maxBoundX, x); 95 | } 96 | buffer_back[pos] = buffer[pos]; 97 | } 98 | yield(); 99 | } 100 | 101 | // If the minBoundY wasn't updated 102 | // we can savely assume that buffer_back[pos] == buffer[pos] 103 | // holdes true for all values of pos 104 | if (minBoundY == ~0) return; 105 | 106 | sendCommand(COLUMNADDR); 107 | sendCommand(minBoundX); 108 | sendCommand(maxBoundX); 109 | 110 | sendCommand(PAGEADDR); 111 | sendCommand(minBoundY); 112 | sendCommand(maxBoundY); 113 | 114 | digitalWrite(_cs, HIGH); 115 | digitalWrite(_dc, HIGH); // data mode 116 | digitalWrite(_cs, LOW); 117 | for (y = minBoundY; y <= maxBoundY; y++) { 118 | for (x = minBoundX; x <= maxBoundX; x++) { 119 | SPI.transfer(buffer[x + y * displayWidth]); 120 | } 121 | yield(); 122 | } 123 | digitalWrite(_cs, HIGH); 124 | #else 125 | // No double buffering 126 | sendCommand(COLUMNADDR); 127 | sendCommand(0x0); 128 | sendCommand(0x7F); 129 | 130 | sendCommand(PAGEADDR); 131 | sendCommand(0x0); 132 | 133 | if (geometry == GEOMETRY_128_64) { 134 | sendCommand(0x7); 135 | } else if (geometry == GEOMETRY_128_32) { 136 | sendCommand(0x3); 137 | } 138 | 139 | digitalWrite(_cs, HIGH); 140 | digitalWrite(_dc, HIGH); // data mode 141 | digitalWrite(_cs, LOW); 142 | for (uint16_t i=0; i 0) { 63 | u1_t need_padding = 0; 64 | for (u1_t i = 0; i < 16; ++i, ++buf, --len) { 65 | if (len == 0) { 66 | // The message is padded with 0x80 and then zeroes. 67 | // Since zeroes are no-op for xor, we can just skip them 68 | // and leave AESAUX unchanged for them. 69 | AESaux[i] ^= 0x80; 70 | need_padding = 1; 71 | break; 72 | } 73 | AESaux[i] ^= *buf; 74 | } 75 | 76 | if (len == 0) { 77 | // Final block, xor with K1 or K2. K1 and K2 are calculated 78 | // by encrypting the all-zeroes block and then applying some 79 | // shifts and xor on that. 80 | u1_t final_key[16]; 81 | memset(final_key, 0, sizeof(final_key)); 82 | lmic_aes_encrypt(final_key, AESkey); 83 | 84 | // Calculate K1 85 | u1_t msb = final_key[0] & 0x80; 86 | shift_left(final_key, sizeof(final_key)); 87 | if (msb) 88 | final_key[sizeof(final_key)-1] ^= 0x87; 89 | 90 | // If the final block was not complete, calculate K2 from K1 91 | if (need_padding) { 92 | msb = final_key[0] & 0x80; 93 | shift_left(final_key, sizeof(final_key)); 94 | if (msb) 95 | final_key[sizeof(final_key)-1] ^= 0x87; 96 | } 97 | 98 | // Xor with K1 or K2 99 | for (u1_t i = 0; i < sizeof(final_key); ++i) 100 | AESaux[i] ^= final_key[i]; 101 | } 102 | 103 | lmic_aes_encrypt(AESaux, AESkey); 104 | } 105 | } 106 | 107 | // Run AES-CTR using the key in AESKEY and using AESAUX as the 108 | // counter block. The last byte of the counter block will be incremented 109 | // for every block. The given buffer will be encrypted in place. 110 | static void os_aes_ctr (xref2u1_t buf, u2_t len) { 111 | u1_t ctr[16]; 112 | while (len) { 113 | // Encrypt the counter block with the selected key 114 | memcpy(ctr, AESaux, sizeof(ctr)); 115 | lmic_aes_encrypt(ctr, AESkey); 116 | 117 | // Xor the payload with the resulting ciphertext 118 | for (u1_t i = 0; i < 16 && len > 0; i++, len--, buf++) 119 | *buf ^= ctr[i]; 120 | 121 | // Increment the block index byte 122 | AESaux[15]++; 123 | } 124 | } 125 | 126 | u4_t os_aes (u1_t mode, xref2u1_t buf, u2_t len) { 127 | switch (mode & ~AES_MICNOAUX) { 128 | case AES_MIC: 129 | os_aes_cmac(buf, len, /* prepend_aux */ !(mode & AES_MICNOAUX)); 130 | return os_rmsbf4(AESaux); 131 | 132 | case AES_ENC: 133 | // TODO: Check / handle when len is not a multiple of 16 134 | for (u1_t i = 0; i < len; i += 16) 135 | lmic_aes_encrypt(buf+i, AESkey); 136 | break; 137 | 138 | case AES_CTR: 139 | os_aes_ctr(buf, len); 140 | break; 141 | } 142 | return 0; 143 | } 144 | 145 | #endif // !defined(USE_ORIGINAL_AES) 146 | -------------------------------------------------------------------------------- /lib/ESP8266_SSD1306_ID562/SH1106Wire.h: -------------------------------------------------------------------------------- 1 | /** 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2018 by ThingPulse, Daniel Eichhorn 5 | * Copyright (c) 2018 by Fabrice Weinberg 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | * 25 | * ThingPulse invests considerable time and money to develop these open source libraries. 26 | * Please support us by buying our products (and not the clones) from 27 | * https://thingpulse.com 28 | * 29 | */ 30 | 31 | #ifndef SH1106Wire_h 32 | #define SH1106Wire_h 33 | 34 | #include "OLEDDisplay.h" 35 | #include 36 | 37 | #define SH1106_SET_PUMP_VOLTAGE 0X30 38 | #define SH1106_SET_PUMP_MODE 0XAD 39 | #define SH1106_PUMP_ON 0X8B 40 | #define SH1106_PUMP_OFF 0X8A 41 | //-------------------------------------- 42 | 43 | class SH1106Wire : public OLEDDisplay { 44 | private: 45 | uint8_t _address; 46 | uint8_t _sda; 47 | uint8_t _scl; 48 | 49 | public: 50 | SH1106Wire(uint8_t _address, uint8_t _sda, uint8_t _scl, OLEDDISPLAY_GEOMETRY g = GEOMETRY_128_64) { 51 | setGeometry(g); 52 | 53 | this->_address = _address; 54 | this->_sda = _sda; 55 | this->_scl = _scl; 56 | } 57 | 58 | bool connect() { 59 | Wire.begin(this->_sda, this->_scl); 60 | // Let's use ~700khz if ESP8266 is in 160Mhz mode 61 | // this will be limited to ~400khz if the ESP8266 in 80Mhz mode. 62 | Wire.setClock(700000); 63 | return true; 64 | } 65 | 66 | void display(void) { 67 | #ifdef OLEDDISPLAY_DOUBLE_BUFFER 68 | uint8_t minBoundY = ~0; 69 | uint8_t maxBoundY = 0; 70 | 71 | uint8_t minBoundX = ~0; 72 | uint8_t maxBoundX = 0; 73 | 74 | uint8_t x, y; 75 | 76 | // Calculate the Y bounding box of changes 77 | // and copy buffer[pos] to buffer_back[pos]; 78 | for (y = 0; y < (displayHeight / 8); y++) { 79 | for (x = 0; x < displayWidth; x++) { 80 | uint16_t pos = x + y * displayWidth; 81 | if (buffer[pos] != buffer_back[pos]) { 82 | minBoundY = _min(minBoundY, y); 83 | maxBoundY = _max(maxBoundY, y); 84 | minBoundX = _min(minBoundX, x); 85 | maxBoundX = _max(maxBoundX, x); 86 | } 87 | buffer_back[pos] = buffer[pos]; 88 | } 89 | yield(); 90 | } 91 | 92 | // If the minBoundY wasn't updated 93 | // we can savely assume that buffer_back[pos] == buffer[pos] 94 | // holdes true for all values of pos 95 | if (minBoundY == ~0) return; 96 | 97 | // Calculate the colum offset 98 | uint8_t minBoundXp2H = (minBoundX + 2) & 0x0F; 99 | uint8_t minBoundXp2L = 0x10 | ((minBoundX + 2) >> 4 ); 100 | 101 | byte k = 0; 102 | for (y = minBoundY; y <= maxBoundY; y++) { 103 | sendCommand(0xB0 + y); 104 | sendCommand(minBoundXp2H); 105 | sendCommand(minBoundXp2L); 106 | for (x = minBoundX; x <= maxBoundX; x++) { 107 | if (k == 0) { 108 | Wire.beginTransmission(_address); 109 | Wire.write(0x40); 110 | } 111 | Wire.write(buffer[x + y * displayWidth]); 112 | k++; 113 | if (k == 16) { 114 | Wire.endTransmission(); 115 | k = 0; 116 | } 117 | } 118 | if (k != 0) { 119 | Wire.endTransmission(); 120 | k = 0; 121 | } 122 | yield(); 123 | } 124 | 125 | if (k != 0) { 126 | Wire.endTransmission(); 127 | } 128 | #else 129 | uint8_t * p = &buffer[0]; 130 | for (uint8_t y=0; y<8; y++) { 131 | sendCommand(0xB0+y); 132 | sendCommand(0x02); 133 | sendCommand(0x10); 134 | for( uint8_t x=0; x<8; x++) { 135 | Wire.beginTransmission(_address); 136 | Wire.write(0x40); 137 | for (uint8_t k = 0; k < 16; k++) { 138 | Wire.write(*p++); 139 | } 140 | Wire.endTransmission(); 141 | } 142 | } 143 | #endif 144 | } 145 | 146 | private: 147 | inline void sendCommand(uint8_t command) __attribute__((always_inline)){ 148 | Wire.beginTransmission(_address); 149 | Wire.write(0x80); 150 | Wire.write(command); 151 | Wire.endTransmission(); 152 | } 153 | 154 | 155 | }; 156 | 157 | #endif 158 | -------------------------------------------------------------------------------- /lib/ESP8266_SSD1306_ID562/SSD1306Brzo.h: -------------------------------------------------------------------------------- 1 | /** 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2018 by ThingPulse, Daniel Eichhorn 5 | * Copyright (c) 2018 by Fabrice Weinberg 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | * 25 | * ThingPulse invests considerable time and money to develop these open source libraries. 26 | * Please support us by buying our products (and not the clones) from 27 | * https://thingpulse.com 28 | * 29 | */ 30 | 31 | #ifndef SSD1306Brzo_h 32 | #define SSD1306Brzo_h 33 | 34 | #include "OLEDDisplay.h" 35 | #include 36 | 37 | #if F_CPU == 160000000L 38 | #define BRZO_I2C_SPEED 1000 39 | #else 40 | #define BRZO_I2C_SPEED 800 41 | #endif 42 | 43 | class SSD1306Brzo : public OLEDDisplay { 44 | private: 45 | uint8_t _address; 46 | uint8_t _sda; 47 | uint8_t _scl; 48 | 49 | public: 50 | SSD1306Brzo(uint8_t _address, uint8_t _sda, uint8_t _scl, OLEDDISPLAY_GEOMETRY g = GEOMETRY_128_64) { 51 | setGeometry(g); 52 | 53 | this->_address = _address; 54 | this->_sda = _sda; 55 | this->_scl = _scl; 56 | } 57 | 58 | bool connect(){ 59 | brzo_i2c_setup(_sda, _scl, 0); 60 | return true; 61 | } 62 | 63 | void display(void) { 64 | #ifdef OLEDDISPLAY_DOUBLE_BUFFER 65 | uint8_t minBoundY = ~0; 66 | uint8_t maxBoundY = 0; 67 | 68 | uint8_t minBoundX = ~0; 69 | uint8_t maxBoundX = 0; 70 | 71 | uint8_t x, y; 72 | 73 | // Calculate the Y bounding box of changes 74 | // and copy buffer[pos] to buffer_back[pos]; 75 | for (y = 0; y < (displayHeight / 8); y++) { 76 | for (x = 0; x < displayWidth; x++) { 77 | uint16_t pos = x + y * displayWidth; 78 | if (buffer[pos] != buffer_back[pos]) { 79 | minBoundY = _min(minBoundY, y); 80 | maxBoundY = _max(maxBoundY, y); 81 | minBoundX = _min(minBoundX, x); 82 | maxBoundX = _max(maxBoundX, x); 83 | } 84 | buffer_back[pos] = buffer[pos]; 85 | } 86 | yield(); 87 | } 88 | 89 | // If the minBoundY wasn't updated 90 | // we can savely assume that buffer_back[pos] == buffer[pos] 91 | // holdes true for all values of pos 92 | if (minBoundY == ~0) return; 93 | 94 | sendCommand(COLUMNADDR); 95 | sendCommand(minBoundX); 96 | sendCommand(maxBoundX); 97 | 98 | sendCommand(PAGEADDR); 99 | sendCommand(minBoundY); 100 | sendCommand(maxBoundY); 101 | 102 | byte k = 0; 103 | uint8_t sendBuffer[17]; 104 | sendBuffer[0] = 0x40; 105 | brzo_i2c_start_transaction(this->_address, BRZO_I2C_SPEED); 106 | for (y = minBoundY; y <= maxBoundY; y++) { 107 | for (x = minBoundX; x <= maxBoundX; x++) { 108 | k++; 109 | sendBuffer[k] = buffer[x + y * displayWidth]; 110 | if (k == 16) { 111 | brzo_i2c_write(sendBuffer, 17, true); 112 | k = 0; 113 | } 114 | } 115 | yield(); 116 | } 117 | brzo_i2c_write(sendBuffer, k + 1, true); 118 | brzo_i2c_end_transaction(); 119 | #else 120 | // No double buffering 121 | sendCommand(COLUMNADDR); 122 | sendCommand(0x0); 123 | sendCommand(0x7F); 124 | 125 | sendCommand(PAGEADDR); 126 | sendCommand(0x0); 127 | 128 | if (geometry == GEOMETRY_128_64) { 129 | sendCommand(0x7); 130 | } else if (geometry == GEOMETRY_128_32) { 131 | sendCommand(0x3); 132 | } 133 | 134 | uint8_t sendBuffer[17]; 135 | sendBuffer[0] = 0x40; 136 | brzo_i2c_start_transaction(this->_address, BRZO_I2C_SPEED); 137 | for (uint16_t i=0; i 16 | #include 17 | #include 18 | 19 | #if !defined(DISABLE_INVERT_IQ_ON_RX) 20 | #error This example requires DISABLE_INVERT_IQ_ON_RX to be set. Update \ 21 | config.h in the lmic library to set it. 22 | #endif 23 | 24 | // How often to send a packet. Note that this sketch bypasses the normal 25 | // LMIC duty cycle limiting, so when you change anything in this sketch 26 | // (payload length, frequency, spreading factor), be sure to check if 27 | // this interval should not also be increased. 28 | // See this spreadsheet for an easy airtime and duty cycle calculator: 29 | // https://docs.google.com/spreadsheets/d/1voGAtQAjC1qBmaVuP1ApNKs1ekgUjavHuVQIXyYSvNc 30 | #define TX_INTERVAL 2000 31 | 32 | // Pin mapping 33 | const lmic_pinmap lmic_pins = { 34 | .nss = 6, 35 | .rxtx = LMIC_UNUSED_PIN, 36 | .rst = 5, 37 | .dio = {2, 3, 4}, 38 | }; 39 | 40 | 41 | // These callbacks are only used in over-the-air activation, so they are 42 | // left empty here (we cannot leave them out completely unless 43 | // DISABLE_JOIN is set in config.h, otherwise the linker will complain). 44 | void os_getArtEui (u1_t* buf) { } 45 | void os_getDevEui (u1_t* buf) { } 46 | void os_getDevKey (u1_t* buf) { } 47 | 48 | void onEvent (ev_t ev) { 49 | } 50 | 51 | osjob_t txjob; 52 | osjob_t timeoutjob; 53 | static void tx_func (osjob_t* job); 54 | 55 | // Transmit the given string and call the given function afterwards 56 | void tx(const char *str, osjobcb_t func) { 57 | os_radio(RADIO_RST); // Stop RX first 58 | delay(1); // Wait a bit, without this os_radio below asserts, apparently because the state hasn't changed yet 59 | LMIC.dataLen = 0; 60 | while (*str) 61 | LMIC.frame[LMIC.dataLen++] = *str++; 62 | LMIC.osjob.func = func; 63 | os_radio(RADIO_TX); 64 | Serial.println("TX"); 65 | } 66 | 67 | // Enable rx mode and call func when a packet is received 68 | void rx(osjobcb_t func) { 69 | LMIC.osjob.func = func; 70 | LMIC.rxtime = os_getTime(); // RX _now_ 71 | // Enable "continuous" RX (e.g. without a timeout, still stops after 72 | // receiving a packet) 73 | os_radio(RADIO_RXON); 74 | Serial.println("RX"); 75 | } 76 | 77 | static void rxtimeout_func(osjob_t *job) { 78 | digitalWrite(LED_BUILTIN, LOW); // off 79 | } 80 | 81 | static void rx_func (osjob_t* job) { 82 | // Blink once to confirm reception and then keep the led on 83 | digitalWrite(LED_BUILTIN, LOW); // off 84 | delay(10); 85 | digitalWrite(LED_BUILTIN, HIGH); // on 86 | 87 | // Timeout RX (i.e. update led status) after 3 periods without RX 88 | os_setTimedCallback(&timeoutjob, os_getTime() + ms2osticks(3*TX_INTERVAL), rxtimeout_func); 89 | 90 | // Reschedule TX so that it should not collide with the other side's 91 | // next TX 92 | os_setTimedCallback(&txjob, os_getTime() + ms2osticks(TX_INTERVAL/2), tx_func); 93 | 94 | Serial.print("Got "); 95 | Serial.print(LMIC.dataLen); 96 | Serial.println(" bytes"); 97 | Serial.write(LMIC.frame, LMIC.dataLen); 98 | Serial.println(); 99 | 100 | // Restart RX 101 | rx(rx_func); 102 | } 103 | 104 | static void txdone_func (osjob_t* job) { 105 | rx(rx_func); 106 | } 107 | 108 | // log text to USART and toggle LED 109 | static void tx_func (osjob_t* job) { 110 | // say hello 111 | tx("Hello, world!", txdone_func); 112 | // reschedule job every TX_INTERVAL (plus a bit of random to prevent 113 | // systematic collisions), unless packets are received, then rx_func 114 | // will reschedule at half this time. 115 | os_setTimedCallback(job, os_getTime() + ms2osticks(TX_INTERVAL + random(500)), tx_func); 116 | } 117 | 118 | // application entry point 119 | void setup() { 120 | Serial.begin(115200); 121 | Serial.println("Starting"); 122 | #ifdef VCC_ENABLE 123 | // For Pinoccio Scout boards 124 | pinMode(VCC_ENABLE, OUTPUT); 125 | digitalWrite(VCC_ENABLE, HIGH); 126 | delay(1000); 127 | #endif 128 | 129 | pinMode(LED_BUILTIN, OUTPUT); 130 | 131 | // initialize runtime env 132 | os_init(); 133 | 134 | // Set up these settings once, and use them for both TX and RX 135 | 136 | #if defined(CFG_eu868) 137 | // Use a frequency in the g3 which allows 10% duty cycling. 138 | LMIC.freq = 869525000; 139 | #elif defined(CFG_us915) 140 | LMIC.freq = 902300000; 141 | #endif 142 | 143 | // Maximum TX power 144 | LMIC.txpow = 27; 145 | // Use a medium spread factor. This can be increased up to SF12 for 146 | // better range, but then the interval should be (significantly) 147 | // lowered to comply with duty cycle limits as well. 148 | LMIC.datarate = DR_SF9; 149 | // This sets CR 4/5, BW125 (except for DR_SF7B, which uses BW250) 150 | LMIC.rps = updr2rps(LMIC.datarate); 151 | 152 | Serial.println("Started"); 153 | Serial.flush(); 154 | 155 | // setup initial job 156 | os_setCallback(&txjob, tx_func); 157 | } 158 | 159 | void loop() { 160 | // execute scheduled jobs and events 161 | os_runloop_once(); 162 | } 163 | -------------------------------------------------------------------------------- /lib/ESP8266_SSD1306_ID562/SSD1306Wire.h: -------------------------------------------------------------------------------- 1 | /** 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2018 by ThingPulse, Daniel Eichhorn 5 | * Copyright (c) 2018 by Fabrice Weinberg 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | * 25 | * ThingPulse invests considerable time and money to develop these open source libraries. 26 | * Please support us by buying our products (and not the clones) from 27 | * https://thingpulse.com 28 | * 29 | */ 30 | 31 | #ifndef SSD1306Wire_h 32 | #define SSD1306Wire_h 33 | 34 | #include "OLEDDisplay.h" 35 | #include 36 | 37 | class SSD1306Wire : public OLEDDisplay { 38 | private: 39 | uint8_t _address; 40 | uint8_t _sda; 41 | uint8_t _scl; 42 | bool _doI2cAutoInit = false; 43 | 44 | public: 45 | SSD1306Wire(uint8_t _address, uint8_t _sda, uint8_t _scl, OLEDDISPLAY_GEOMETRY g = GEOMETRY_128_64) { 46 | setGeometry(g); 47 | 48 | this->_address = _address; 49 | this->_sda = _sda; 50 | this->_scl = _scl; 51 | } 52 | 53 | bool connect() { 54 | Wire.begin(this->_sda, this->_scl); 55 | // Let's use ~700khz if ESP8266 is in 160Mhz mode 56 | // this will be limited to ~400khz if the ESP8266 in 80Mhz mode. 57 | Wire.setClock(700000); 58 | return true; 59 | } 60 | 61 | void display(void) { 62 | initI2cIfNeccesary(); 63 | const int x_offset = (128 - this->width()) / 2; 64 | #ifdef OLEDDISPLAY_DOUBLE_BUFFER 65 | uint8_t minBoundY = ~0; 66 | uint8_t maxBoundY = 0; 67 | 68 | uint8_t minBoundX = ~0; 69 | uint8_t maxBoundX = 0; 70 | uint8_t x, y; 71 | 72 | // Calculate the Y bounding box of changes 73 | // and copy buffer[pos] to buffer_back[pos]; 74 | for (y = 0; y < (this->height() / 8); y++) { 75 | for (x = 0; x < this->width(); x++) { 76 | uint16_t pos = x + y * this->width(); 77 | if (buffer[pos] != buffer_back[pos]) { 78 | minBoundY = _min(minBoundY, y); 79 | maxBoundY = _max(maxBoundY, y); 80 | minBoundX = _min(minBoundX, x); 81 | maxBoundX = _max(maxBoundX, x); 82 | } 83 | buffer_back[pos] = buffer[pos]; 84 | } 85 | yield(); 86 | } 87 | 88 | // If the minBoundY wasn't updated 89 | // we can savely assume that buffer_back[pos] == buffer[pos] 90 | // holdes true for all values of pos 91 | 92 | if (minBoundY == (uint8_t)(~0)) return; 93 | 94 | sendCommand(COLUMNADDR); 95 | sendCommand(x_offset + minBoundX); 96 | sendCommand(x_offset + maxBoundX); 97 | 98 | sendCommand(PAGEADDR); 99 | sendCommand(minBoundY); 100 | sendCommand(maxBoundY); 101 | 102 | byte k = 0; 103 | for (y = minBoundY; y <= maxBoundY; y++) { 104 | for (x = minBoundX; x <= maxBoundX; x++) { 105 | if (k == 0) { 106 | Wire.beginTransmission(_address); 107 | Wire.write(0x40); 108 | } 109 | 110 | Wire.write(buffer[x + y * this->width()]); 111 | k++; 112 | if (k == 16) { 113 | Wire.endTransmission(); 114 | k = 0; 115 | } 116 | } 117 | yield(); 118 | } 119 | 120 | if (k != 0) { 121 | Wire.endTransmission(); 122 | } 123 | #else 124 | 125 | sendCommand(COLUMNADDR); 126 | sendCommand(x_offset); 127 | sendCommand(x_offset + (this->width() - 1)); 128 | 129 | sendCommand(PAGEADDR); 130 | sendCommand(0x0); 131 | sendCommand((this->height() / 8) - 1); 132 | 133 | if (geometry == GEOMETRY_128_64) { 134 | sendCommand(0x7); 135 | } else if (geometry == GEOMETRY_128_32) { 136 | sendCommand(0x3); 137 | } 138 | 139 | for (uint16_t i=0; i < displayBufferSize; i++) { 140 | Wire.beginTransmission(this->_address); 141 | Wire.write(0x40); 142 | for (uint8_t x = 0; x < 16; x++) { 143 | Wire.write(buffer[i]); 144 | i++; 145 | } 146 | i--; 147 | Wire.endTransmission(); 148 | } 149 | #endif 150 | } 151 | 152 | void setI2cAutoInit(bool doI2cAutoInit) { 153 | _doI2cAutoInit = doI2cAutoInit; 154 | } 155 | 156 | private: 157 | inline void sendCommand(uint8_t command) __attribute__((always_inline)){ 158 | initI2cIfNeccesary(); 159 | Wire.beginTransmission(_address); 160 | Wire.write(0x80); 161 | Wire.write(command); 162 | Wire.endTransmission(); 163 | } 164 | 165 | void initI2cIfNeccesary() { 166 | if (_doI2cAutoInit) { 167 | Wire.begin(this->_sda, this->_scl); 168 | } 169 | } 170 | 171 | }; 172 | 173 | #endif 174 | -------------------------------------------------------------------------------- /lib/ESP8266_SSD1306_ID562/examples/SSD1306SimpleDemo/SSD1306SimpleDemo.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2018 by ThingPulse, Daniel Eichhorn 5 | * Copyright (c) 2018 by Fabrice Weinberg 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | * 25 | * ThingPulse invests considerable time and money to develop these open source libraries. 26 | * Please support us by buying our products (and not the clones) from 27 | * https://thingpulse.com 28 | * 29 | */ 30 | 31 | // Include the correct display library 32 | // For a connection via I2C using Wire include 33 | #include // Only needed for Arduino 1.6.5 and earlier 34 | #include "SSD1306.h" // alias for `#include "SSD1306Wire.h"` 35 | // or #include "SH1106.h" alias for `#include "SH1106Wire.h"` 36 | // For a connection via I2C using brzo_i2c (must be installed) include 37 | // #include // Only needed for Arduino 1.6.5 and earlier 38 | // #include "SSD1306Brzo.h" 39 | // #include "SH1106Brzo.h" 40 | // For a connection via SPI include 41 | // #include // Only needed for Arduino 1.6.5 and earlier 42 | // #include "SSD1306Spi.h" 43 | // #include "SH1106SPi.h" 44 | 45 | // Include custom images 46 | #include "images.h" 47 | 48 | // Initialize the OLED display using SPI 49 | // D5 -> CLK 50 | // D7 -> MOSI (DOUT) 51 | // D0 -> RES 52 | // D2 -> DC 53 | // D8 -> CS 54 | // SSD1306Spi display(D0, D2, D8); 55 | // or 56 | // SH1106Spi display(D0, D2); 57 | 58 | // Initialize the OLED display using brzo_i2c 59 | // D3 -> SDA 60 | // D5 -> SCL 61 | // SSD1306Brzo display(0x3c, D3, D5); 62 | // or 63 | // SH1106Brzo display(0x3c, D3, D5); 64 | 65 | // Initialize the OLED display using Wire library 66 | SSD1306 display(0x3c, D3, D5); 67 | // SH1106 display(0x3c, D3, D5); 68 | 69 | 70 | #define DEMO_DURATION 3000 71 | typedef void (*Demo)(void); 72 | 73 | int demoMode = 0; 74 | int counter = 1; 75 | 76 | void setup() { 77 | Serial.begin(115200); 78 | Serial.println(); 79 | Serial.println(); 80 | 81 | 82 | // Initialising the UI will init the display too. 83 | display.init(); 84 | 85 | display.flipScreenVertically(); 86 | display.setFont(ArialMT_Plain_10); 87 | 88 | } 89 | 90 | void drawFontFaceDemo() { 91 | // Font Demo1 92 | // create more fonts at http://oleddisplay.squix.ch/ 93 | display.setTextAlignment(TEXT_ALIGN_LEFT); 94 | display.setFont(ArialMT_Plain_10); 95 | display.drawString(0, 0, "Hello world"); 96 | display.setFont(ArialMT_Plain_16); 97 | display.drawString(0, 10, "Hello world"); 98 | display.setFont(ArialMT_Plain_24); 99 | display.drawString(0, 26, "Hello world"); 100 | } 101 | 102 | void drawTextFlowDemo() { 103 | display.setFont(ArialMT_Plain_10); 104 | display.setTextAlignment(TEXT_ALIGN_LEFT); 105 | display.drawStringMaxWidth(0, 0, 128, 106 | "Lorem ipsum\n dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore." ); 107 | } 108 | 109 | void drawTextAlignmentDemo() { 110 | // Text alignment demo 111 | display.setFont(ArialMT_Plain_10); 112 | 113 | // The coordinates define the left starting point of the text 114 | display.setTextAlignment(TEXT_ALIGN_LEFT); 115 | display.drawString(0, 10, "Left aligned (0,10)"); 116 | 117 | // The coordinates define the center of the text 118 | display.setTextAlignment(TEXT_ALIGN_CENTER); 119 | display.drawString(64, 22, "Center aligned (64,22)"); 120 | 121 | // The coordinates define the right end of the text 122 | display.setTextAlignment(TEXT_ALIGN_RIGHT); 123 | display.drawString(128, 33, "Right aligned (128,33)"); 124 | } 125 | 126 | void drawRectDemo() { 127 | // Draw a pixel at given position 128 | for (int i = 0; i < 10; i++) { 129 | display.setPixel(i, i); 130 | display.setPixel(10 - i, i); 131 | } 132 | display.drawRect(12, 12, 20, 20); 133 | 134 | // Fill the rectangle 135 | display.fillRect(14, 14, 17, 17); 136 | 137 | // Draw a line horizontally 138 | display.drawHorizontalLine(0, 40, 20); 139 | 140 | // Draw a line horizontally 141 | display.drawVerticalLine(40, 0, 20); 142 | } 143 | 144 | void drawCircleDemo() { 145 | for (int i=1; i < 8; i++) { 146 | display.setColor(WHITE); 147 | display.drawCircle(32, 32, i*3); 148 | if (i % 2 == 0) { 149 | display.setColor(BLACK); 150 | } 151 | display.fillCircle(96, 32, 32 - i* 3); 152 | } 153 | } 154 | 155 | void drawProgressBarDemo() { 156 | int progress = (counter / 5) % 100; 157 | // draw the progress bar 158 | display.drawProgressBar(0, 32, 120, 10, progress); 159 | 160 | // draw the percentage as String 161 | display.setTextAlignment(TEXT_ALIGN_CENTER); 162 | display.drawString(64, 15, String(progress) + "%"); 163 | } 164 | 165 | void drawImageDemo() { 166 | // see http://blog.squix.org/2015/05/esp8266-nodemcu-how-to-create-xbm.html 167 | // on how to create xbm files 168 | display.drawXbm(34, 14, WiFi_Logo_width, WiFi_Logo_height, WiFi_Logo_bits); 169 | } 170 | 171 | Demo demos[] = {drawFontFaceDemo, drawTextFlowDemo, drawTextAlignmentDemo, drawRectDemo, drawCircleDemo, drawProgressBarDemo, drawImageDemo}; 172 | int demoLength = (sizeof(demos) / sizeof(Demo)); 173 | long timeSinceLastModeSwitch = 0; 174 | 175 | void loop() { 176 | // clear the display 177 | display.clear(); 178 | // draw the current demo method 179 | demos[demoMode](); 180 | 181 | display.setTextAlignment(TEXT_ALIGN_RIGHT); 182 | display.drawString(10, 128, String(millis())); 183 | // write the buffer to the display 184 | display.display(); 185 | 186 | if (millis() - timeSinceLastModeSwitch > DEMO_DURATION) { 187 | demoMode = (demoMode + 1) % demoLength; 188 | timeSinceLastModeSwitch = millis(); 189 | } 190 | counter++; 191 | delay(10); 192 | } 193 | -------------------------------------------------------------------------------- /lib/LMIC-Arduino_ID852/examples/ttn-otaa/ttn-otaa.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman 3 | * 4 | * Permission is hereby granted, free of charge, to anyone 5 | * obtaining a copy of this document and accompanying files, 6 | * to do whatever they want with them without any restriction, 7 | * including, but not limited to, copying, modification and redistribution. 8 | * NO WARRANTY OF ANY KIND IS PROVIDED. 9 | * 10 | * This example sends a valid LoRaWAN packet with payload "Hello, 11 | * world!", using frequency and encryption settings matching those of 12 | * the The Things Network. 13 | * 14 | * This uses OTAA (Over-the-air activation), where where a DevEUI and 15 | * application key is configured, which are used in an over-the-air 16 | * activation procedure where a DevAddr and session keys are 17 | * assigned/generated for use with all further communication. 18 | * 19 | * Note: LoRaWAN per sub-band duty-cycle limitation is enforced (1% in 20 | * g1, 0.1% in g2), but not the TTN fair usage policy (which is probably 21 | * violated by this sketch when left running for longer)! 22 | 23 | * To use this sketch, first register your application and device with 24 | * the things network, to set or generate an AppEUI, DevEUI and AppKey. 25 | * Multiple devices can use the same AppEUI, but each device has its own 26 | * DevEUI and AppKey. 27 | * 28 | * Do not forget to define the radio type correctly in config.h. 29 | * 30 | *******************************************************************************/ 31 | 32 | #include 33 | #include 34 | #include 35 | 36 | // This EUI must be in little-endian format, so least-significant-byte 37 | // first. When copying an EUI from ttnctl output, this means to reverse 38 | // the bytes. For TTN issued EUIs the last bytes should be 0xD5, 0xB3, 39 | // 0x70. 40 | static const u1_t PROGMEM APPEUI[8]={ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 41 | void os_getArtEui (u1_t* buf) { memcpy_P(buf, APPEUI, 8);} 42 | 43 | // This should also be in little endian format, see above. 44 | static const u1_t PROGMEM DEVEUI[8]={ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 45 | void os_getDevEui (u1_t* buf) { memcpy_P(buf, DEVEUI, 8);} 46 | 47 | // This key should be in big endian format (or, since it is not really a 48 | // number but a block of memory, endianness does not really apply). In 49 | // practice, a key taken from ttnctl can be copied as-is. 50 | // The key shown here is the semtech default key. 51 | static const u1_t PROGMEM APPKEY[16] = { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }; 52 | void os_getDevKey (u1_t* buf) { memcpy_P(buf, APPKEY, 16);} 53 | 54 | static uint8_t mydata[] = "Hello, world!"; 55 | static osjob_t sendjob; 56 | 57 | // Schedule TX every this many seconds (might become longer due to duty 58 | // cycle limitations). 59 | const unsigned TX_INTERVAL = 60; 60 | 61 | // Pin mapping 62 | const lmic_pinmap lmic_pins = { 63 | .nss = 6, 64 | .rxtx = LMIC_UNUSED_PIN, 65 | .rst = 5, 66 | .dio = {2, 3, 4}, 67 | }; 68 | 69 | void onEvent (ev_t ev) { 70 | Serial.print(os_getTime()); 71 | Serial.print(": "); 72 | switch(ev) { 73 | case EV_SCAN_TIMEOUT: 74 | Serial.println(F("EV_SCAN_TIMEOUT")); 75 | break; 76 | case EV_BEACON_FOUND: 77 | Serial.println(F("EV_BEACON_FOUND")); 78 | break; 79 | case EV_BEACON_MISSED: 80 | Serial.println(F("EV_BEACON_MISSED")); 81 | break; 82 | case EV_BEACON_TRACKED: 83 | Serial.println(F("EV_BEACON_TRACKED")); 84 | break; 85 | case EV_JOINING: 86 | Serial.println(F("EV_JOINING")); 87 | break; 88 | case EV_JOINED: 89 | Serial.println(F("EV_JOINED")); 90 | 91 | // Disable link check validation (automatically enabled 92 | // during join, but not supported by TTN at this time). 93 | LMIC_setLinkCheckMode(0); 94 | break; 95 | case EV_RFU1: 96 | Serial.println(F("EV_RFU1")); 97 | break; 98 | case EV_JOIN_FAILED: 99 | Serial.println(F("EV_JOIN_FAILED")); 100 | break; 101 | case EV_REJOIN_FAILED: 102 | Serial.println(F("EV_REJOIN_FAILED")); 103 | break; 104 | break; 105 | case EV_TXCOMPLETE: 106 | Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)")); 107 | if (LMIC.txrxFlags & TXRX_ACK) 108 | Serial.println(F("Received ack")); 109 | if (LMIC.dataLen) { 110 | Serial.println(F("Received ")); 111 | Serial.println(LMIC.dataLen); 112 | Serial.println(F(" bytes of payload")); 113 | } 114 | // Schedule next transmission 115 | os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(TX_INTERVAL), do_send); 116 | break; 117 | case EV_LOST_TSYNC: 118 | Serial.println(F("EV_LOST_TSYNC")); 119 | break; 120 | case EV_RESET: 121 | Serial.println(F("EV_RESET")); 122 | break; 123 | case EV_RXCOMPLETE: 124 | // data received in ping slot 125 | Serial.println(F("EV_RXCOMPLETE")); 126 | break; 127 | case EV_LINK_DEAD: 128 | Serial.println(F("EV_LINK_DEAD")); 129 | break; 130 | case EV_LINK_ALIVE: 131 | Serial.println(F("EV_LINK_ALIVE")); 132 | break; 133 | default: 134 | Serial.println(F("Unknown event")); 135 | break; 136 | } 137 | } 138 | 139 | void do_send(osjob_t* j){ 140 | // Check if there is not a current TX/RX job running 141 | if (LMIC.opmode & OP_TXRXPEND) { 142 | Serial.println(F("OP_TXRXPEND, not sending")); 143 | } else { 144 | // Prepare upstream data transmission at the next possible time. 145 | LMIC_setTxData2(1, mydata, sizeof(mydata)-1, 0); 146 | Serial.println(F("Packet queued")); 147 | } 148 | // Next TX is scheduled after TX_COMPLETE event. 149 | } 150 | 151 | void setup() { 152 | Serial.begin(9600); 153 | Serial.println(F("Starting")); 154 | 155 | #ifdef VCC_ENABLE 156 | // For Pinoccio Scout boards 157 | pinMode(VCC_ENABLE, OUTPUT); 158 | digitalWrite(VCC_ENABLE, HIGH); 159 | delay(1000); 160 | #endif 161 | 162 | // LMIC init 163 | os_init(); 164 | // Reset the MAC state. Session and pending data transfers will be discarded. 165 | LMIC_reset(); 166 | 167 | // Start job (sending automatically starts OTAA too) 168 | do_send(&sendjob); 169 | } 170 | 171 | void loop() { 172 | os_runloop_once(); 173 | } 174 | -------------------------------------------------------------------------------- /lib/ESP8266_SSD1306_ID562/examples/SSD1306UiDemo/SSD1306UiDemo.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2018 by ThingPulse, Daniel Eichhorn 5 | * Copyright (c) 2018 by Fabrice Weinberg 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | * 25 | * ThingPulse invests considerable time and money to develop these open source libraries. 26 | * Please support us by buying our products (and not the clones) from 27 | * https://thingpulse.com 28 | * 29 | */ 30 | 31 | // Include the correct display library 32 | // For a connection via I2C using Wire include 33 | #include // Only needed for Arduino 1.6.5 and earlier 34 | #include "SSD1306.h" // alias for `#include "SSD1306Wire.h"` 35 | // or #include "SH1106.h" alis for `#include "SH1106Wire.h"` 36 | // For a connection via I2C using brzo_i2c (must be installed) include 37 | // #include // Only needed for Arduino 1.6.5 and earlier 38 | // #include "SSD1306Brzo.h" 39 | // #include "SH1106Brzo.h" 40 | // For a connection via SPI include 41 | // #include // Only needed for Arduino 1.6.5 and earlier 42 | // #include "SSD1306Spi.h" 43 | // #include "SH1106SPi.h" 44 | 45 | // Include the UI lib 46 | #include "OLEDDisplayUi.h" 47 | 48 | // Include custom images 49 | 50 | #include "images.h" 51 | 52 | // Use the corresponding display class: 53 | 54 | // Initialize the OLED display using SPI 55 | // D5 -> CLK 56 | // D7 -> MOSI (DOUT) 57 | // D0 -> RES 58 | // D2 -> DC 59 | // D8 -> CS 60 | // SSD1306Spi display(D0, D2, D8); 61 | // or 62 | // SH1106Spi display(D0, D2); 63 | 64 | // Initialize the OLED display using brzo_i2c 65 | // D3 -> SDA 66 | // D5 -> SCL 67 | // SSD1306Brzo display(0x3c, D3, D5); 68 | // or 69 | // SH1106Brzo display(0x3c, D3, D5); 70 | 71 | // Initialize the OLED display using Wire library 72 | SSD1306 display(0x3c, D3, D5); 73 | // SH1106 display(0x3c, D3, D5); 74 | 75 | OLEDDisplayUi ui ( &display ); 76 | 77 | void msOverlay(OLEDDisplay *display, OLEDDisplayUiState* state) { 78 | display->setTextAlignment(TEXT_ALIGN_RIGHT); 79 | display->setFont(ArialMT_Plain_10); 80 | display->drawString(128, 0, String(millis())); 81 | } 82 | 83 | void drawFrame1(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { 84 | // draw an xbm image. 85 | // Please note that everything that should be transitioned 86 | // needs to be drawn relative to x and y 87 | 88 | display->drawXbm(x + 34, y + 14, WiFi_Logo_width, WiFi_Logo_height, WiFi_Logo_bits); 89 | } 90 | 91 | void drawFrame2(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { 92 | // Demonstrates the 3 included default sizes. The fonts come from SSD1306Fonts.h file 93 | // Besides the default fonts there will be a program to convert TrueType fonts into this format 94 | display->setTextAlignment(TEXT_ALIGN_LEFT); 95 | display->setFont(ArialMT_Plain_10); 96 | display->drawString(0 + x, 10 + y, "Arial 10"); 97 | 98 | display->setFont(ArialMT_Plain_16); 99 | display->drawString(0 + x, 20 + y, "Arial 16"); 100 | 101 | display->setFont(ArialMT_Plain_24); 102 | display->drawString(0 + x, 34 + y, "Arial 24"); 103 | } 104 | 105 | void drawFrame3(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { 106 | // Text alignment demo 107 | display->setFont(ArialMT_Plain_10); 108 | 109 | // The coordinates define the left starting point of the text 110 | display->setTextAlignment(TEXT_ALIGN_LEFT); 111 | display->drawString(0 + x, 11 + y, "Left aligned (0,10)"); 112 | 113 | // The coordinates define the center of the text 114 | display->setTextAlignment(TEXT_ALIGN_CENTER); 115 | display->drawString(64 + x, 22 + y, "Center aligned (64,22)"); 116 | 117 | // The coordinates define the right end of the text 118 | display->setTextAlignment(TEXT_ALIGN_RIGHT); 119 | display->drawString(128 + x, 33 + y, "Right aligned (128,33)"); 120 | } 121 | 122 | void drawFrame4(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { 123 | // Demo for drawStringMaxWidth: 124 | // with the third parameter you can define the width after which words will be wrapped. 125 | // Currently only spaces and "-" are allowed for wrapping 126 | display->setTextAlignment(TEXT_ALIGN_LEFT); 127 | display->setFont(ArialMT_Plain_10); 128 | display->drawStringMaxWidth(0 + x, 10 + y, 128, "Lorem ipsum\n dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore."); 129 | } 130 | 131 | void drawFrame5(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { 132 | 133 | } 134 | 135 | // This array keeps function pointers to all frames 136 | // frames are the single views that slide in 137 | FrameCallback frames[] = { drawFrame1, drawFrame2, drawFrame3, drawFrame4, drawFrame5 }; 138 | 139 | // how many frames are there? 140 | int frameCount = 5; 141 | 142 | // Overlays are statically drawn on top of a frame eg. a clock 143 | OverlayCallback overlays[] = { msOverlay }; 144 | int overlaysCount = 1; 145 | 146 | void setup() { 147 | Serial.begin(115200); 148 | Serial.println(); 149 | Serial.println(); 150 | 151 | // The ESP is capable of rendering 60fps in 80Mhz mode 152 | // but that won't give you much time for anything else 153 | // run it in 160Mhz mode or just set it to 30 fps 154 | ui.setTargetFPS(60); 155 | 156 | // Customize the active and inactive symbol 157 | ui.setActiveSymbol(activeSymbol); 158 | ui.setInactiveSymbol(inactiveSymbol); 159 | 160 | // You can change this to 161 | // TOP, LEFT, BOTTOM, RIGHT 162 | ui.setIndicatorPosition(BOTTOM); 163 | 164 | // Defines where the first frame is located in the bar. 165 | ui.setIndicatorDirection(LEFT_RIGHT); 166 | 167 | // You can change the transition that is used 168 | // SLIDE_LEFT, SLIDE_RIGHT, SLIDE_UP, SLIDE_DOWN 169 | ui.setFrameAnimation(SLIDE_LEFT); 170 | 171 | // Add frames 172 | ui.setFrames(frames, frameCount); 173 | 174 | // Add overlays 175 | ui.setOverlays(overlays, overlaysCount); 176 | 177 | // Initialising the UI will init the display too. 178 | ui.init(); 179 | 180 | display.flipScreenVertically(); 181 | 182 | } 183 | 184 | 185 | void loop() { 186 | int remainingTimeBudget = ui.update(); 187 | 188 | if (remainingTimeBudget > 0) { 189 | // You can do some work here 190 | // Don't do stuff if you are below your 191 | // time budget. 192 | delay(remainingTimeBudget); 193 | } 194 | } 195 | -------------------------------------------------------------------------------- /lib/ESP8266_SSD1306_ID562/examples/SSD1306DrawingDemo/SSD1306DrawingDemo.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2018 by ThingPulse, Daniel Eichhorn 5 | * Copyright (c) 2018 by Fabrice Weinberg 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | * 25 | * ThingPulse invests considerable time and money to develop these open source libraries. 26 | * Please support us by buying our products (and not the clones) from 27 | * https://thingpulse.com 28 | * 29 | */ 30 | 31 | // Include the correct display library 32 | // For a connection via I2C using Wire include 33 | #include // Only needed for Arduino 1.6.5 and earlier 34 | #include "SSD1306.h" // alias for `#include "SSD1306Wire.h"` 35 | // or #include "SH1106.h" alis for `#include "SH1106Wire.h"` 36 | // For a connection via I2C using brzo_i2c (must be installed) include 37 | // #include // Only needed for Arduino 1.6.5 and earlier 38 | // #include "SSD1306Brzo.h" 39 | // #include "SH1106Brzo.h" 40 | // For a connection via SPI include 41 | // #include // Only needed for Arduino 1.6.5 and earlier 42 | // #include "SSD1306Spi.h" 43 | // #include "SH1106SPi.h" 44 | 45 | // Use the corresponding display class: 46 | 47 | // Initialize the OLED display using SPI 48 | // D5 -> CLK 49 | // D7 -> MOSI (DOUT) 50 | // D0 -> RES 51 | // D2 -> DC 52 | // D8 -> CS 53 | // SSD1306Spi display(D0, D2, D8); 54 | // or 55 | // SH1106Spi display(D0, D2); 56 | 57 | // Initialize the OLED display using brzo_i2c 58 | // D3 -> SDA 59 | // D5 -> SCL 60 | // SSD1306Brzo display(0x3c, D3, D5); 61 | // or 62 | // SH1106Brzo display(0x3c, D3, D5); 63 | 64 | // Initialize the OLED display using Wire library 65 | SSD1306 display(0x3c, D3, D5); 66 | // SH1106 display(0x3c, D3, D5); 67 | 68 | // Adapted from Adafruit_SSD1306 69 | void drawLines() { 70 | for (int16_t i=0; i=0; i-=4) { 89 | display.drawLine(0, display.getHeight()-1, display.getWidth()-1, i); 90 | display.display(); 91 | delay(10); 92 | } 93 | delay(250); 94 | 95 | display.clear(); 96 | for (int16_t i=display.getWidth()-1; i>=0; i-=4) { 97 | display.drawLine(display.getWidth()-1, display.getHeight()-1, i, 0); 98 | display.display(); 99 | delay(10); 100 | } 101 | for (int16_t i=display.getHeight()-1; i>=0; i-=4) { 102 | display.drawLine(display.getWidth()-1, display.getHeight()-1, 0, i); 103 | display.display(); 104 | delay(10); 105 | } 106 | delay(250); 107 | display.clear(); 108 | for (int16_t i=0; i 31 | 32 | // Include the correct display library 33 | // For a connection via I2C using Wire include 34 | #include // Only needed for Arduino 1.6.5 and earlier 35 | #include "SSD1306.h" // alias for `#include "SSD1306Wire.h"` 36 | // or #include "SH1106.h" alis for `#include "SH1106Wire.h"` 37 | // For a connection via I2C using brzo_i2c (must be installed) include 38 | // #include // Only needed for Arduino 1.6.5 and earlier 39 | // #include "SSD1306Brzo.h" 40 | // #include "SH1106Brzo.h" 41 | // For a connection via SPI include 42 | // #include // Only needed for Arduino 1.6.5 and earlier 43 | // #include "SSD1306Spi.h" 44 | // #include "SH1106SPi.h" 45 | 46 | // Include the UI lib 47 | #include "OLEDDisplayUi.h" 48 | 49 | // Include custom images 50 | #include "images.h" 51 | 52 | // Use the corresponding display class: 53 | 54 | // Initialize the OLED display using SPI 55 | // D5 -> CLK 56 | // D7 -> MOSI (DOUT) 57 | // D0 -> RES 58 | // D2 -> DC 59 | // D8 -> CS 60 | // SSD1306Spi display(D0, D2, D8); 61 | // or 62 | // SH1106Spi display(D0, D2); 63 | 64 | // Initialize the OLED display using brzo_i2c 65 | // D3 -> SDA 66 | // D5 -> SCL 67 | // SSD1306Brzo display(0x3c, D3, D5); 68 | // or 69 | // SH1106Brzo display(0x3c, D3, D5); 70 | 71 | // Initialize the OLED display using Wire library 72 | SSD1306 display(0x3c, D3, D5); 73 | // SH1106 display(0x3c, D3, D5); 74 | 75 | OLEDDisplayUi ui ( &display ); 76 | 77 | int screenW = 128; 78 | int screenH = 64; 79 | int clockCenterX = screenW/2; 80 | int clockCenterY = ((screenH-16)/2)+16; // top yellow part is 16 px height 81 | int clockRadius = 23; 82 | 83 | // utility function for digital clock display: prints leading 0 84 | String twoDigits(int digits){ 85 | if(digits < 10) { 86 | String i = '0'+String(digits); 87 | return i; 88 | } 89 | else { 90 | return String(digits); 91 | } 92 | } 93 | 94 | void clockOverlay(OLEDDisplay *display, OLEDDisplayUiState* state) { 95 | 96 | } 97 | 98 | void analogClockFrame(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { 99 | // ui.disableIndicator(); 100 | 101 | // Draw the clock face 102 | // display->drawCircle(clockCenterX + x, clockCenterY + y, clockRadius); 103 | display->drawCircle(clockCenterX + x, clockCenterY + y, 2); 104 | // 105 | //hour ticks 106 | for( int z=0; z < 360;z= z + 30 ){ 107 | //Begin at 0° and stop at 360° 108 | float angle = z ; 109 | angle = ( angle / 57.29577951 ) ; //Convert degrees to radians 110 | int x2 = ( clockCenterX + ( sin(angle) * clockRadius ) ); 111 | int y2 = ( clockCenterY - ( cos(angle) * clockRadius ) ); 112 | int x3 = ( clockCenterX + ( sin(angle) * ( clockRadius - ( clockRadius / 8 ) ) ) ); 113 | int y3 = ( clockCenterY - ( cos(angle) * ( clockRadius - ( clockRadius / 8 ) ) ) ); 114 | display->drawLine( x2 + x , y2 + y , x3 + x , y3 + y); 115 | } 116 | 117 | // display second hand 118 | float angle = second() * 6 ; 119 | angle = ( angle / 57.29577951 ) ; //Convert degrees to radians 120 | int x3 = ( clockCenterX + ( sin(angle) * ( clockRadius - ( clockRadius / 5 ) ) ) ); 121 | int y3 = ( clockCenterY - ( cos(angle) * ( clockRadius - ( clockRadius / 5 ) ) ) ); 122 | display->drawLine( clockCenterX + x , clockCenterY + y , x3 + x , y3 + y); 123 | // 124 | // display minute hand 125 | angle = minute() * 6 ; 126 | angle = ( angle / 57.29577951 ) ; //Convert degrees to radians 127 | x3 = ( clockCenterX + ( sin(angle) * ( clockRadius - ( clockRadius / 4 ) ) ) ); 128 | y3 = ( clockCenterY - ( cos(angle) * ( clockRadius - ( clockRadius / 4 ) ) ) ); 129 | display->drawLine( clockCenterX + x , clockCenterY + y , x3 + x , y3 + y); 130 | // 131 | // display hour hand 132 | angle = hour() * 30 + int( ( minute() / 12 ) * 6 ) ; 133 | angle = ( angle / 57.29577951 ) ; //Convert degrees to radians 134 | x3 = ( clockCenterX + ( sin(angle) * ( clockRadius - ( clockRadius / 2 ) ) ) ); 135 | y3 = ( clockCenterY - ( cos(angle) * ( clockRadius - ( clockRadius / 2 ) ) ) ); 136 | display->drawLine( clockCenterX + x , clockCenterY + y , x3 + x , y3 + y); 137 | } 138 | 139 | void digitalClockFrame(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { 140 | String timenow = String(hour())+":"+twoDigits(minute())+":"+twoDigits(second()); 141 | display->setTextAlignment(TEXT_ALIGN_CENTER); 142 | display->setFont(ArialMT_Plain_24); 143 | display->drawString(clockCenterX + x , clockCenterY + y, timenow ); 144 | } 145 | 146 | // This array keeps function pointers to all frames 147 | // frames are the single views that slide in 148 | FrameCallback frames[] = { analogClockFrame, digitalClockFrame }; 149 | 150 | // how many frames are there? 151 | int frameCount = 2; 152 | 153 | // Overlays are statically drawn on top of a frame eg. a clock 154 | OverlayCallback overlays[] = { clockOverlay }; 155 | int overlaysCount = 1; 156 | 157 | void setup() { 158 | Serial.begin(9600); 159 | Serial.println(); 160 | 161 | // The ESP is capable of rendering 60fps in 80Mhz mode 162 | // but that won't give you much time for anything else 163 | // run it in 160Mhz mode or just set it to 30 fps 164 | ui.setTargetFPS(60); 165 | 166 | // Customize the active and inactive symbol 167 | ui.setActiveSymbol(activeSymbol); 168 | ui.setInactiveSymbol(inactiveSymbol); 169 | 170 | // You can change this to 171 | // TOP, LEFT, BOTTOM, RIGHT 172 | ui.setIndicatorPosition(TOP); 173 | 174 | // Defines where the first frame is located in the bar. 175 | ui.setIndicatorDirection(LEFT_RIGHT); 176 | 177 | // You can change the transition that is used 178 | // SLIDE_LEFT, SLIDE_RIGHT, SLIDE_UP, SLIDE_DOWN 179 | ui.setFrameAnimation(SLIDE_LEFT); 180 | 181 | // Add frames 182 | ui.setFrames(frames, frameCount); 183 | 184 | // Add overlays 185 | ui.setOverlays(overlays, overlaysCount); 186 | 187 | // Initialising the UI will init the display too. 188 | ui.init(); 189 | 190 | display.flipScreenVertically(); 191 | 192 | unsigned long secsSinceStart = millis(); 193 | // Unix time starts on Jan 1 1970. In seconds, that's 2208988800: 194 | const unsigned long seventyYears = 2208988800UL; 195 | // subtract seventy years: 196 | unsigned long epoch = secsSinceStart - seventyYears * SECS_PER_HOUR; 197 | setTime(epoch); 198 | 199 | } 200 | 201 | 202 | void loop() { 203 | int remainingTimeBudget = ui.update(); 204 | 205 | if (remainingTimeBudget > 0) { 206 | // You can do some work here 207 | // Don't do stuff if you are below your 208 | // time budget. 209 | delay(remainingTimeBudget); 210 | 211 | } 212 | 213 | 214 | } 215 | -------------------------------------------------------------------------------- /lib/LMIC-Arduino_ID852/src/hal/hal.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2015 Matthijs Kooijman 3 | * All rights reserved. This program and the accompanying materials 4 | * are made available under the terms of the Eclipse Public License v1.0 5 | * which accompanies this distribution, and is available at 6 | * http://www.eclipse.org/legal/epl-v10.html 7 | * 8 | * This the HAL to run LMIC on top of the Arduino environment. 9 | *******************************************************************************/ 10 | 11 | #include 12 | #include 13 | #include "../lmic.h" 14 | #include "hal.h" 15 | #include 16 | 17 | // ----------------------------------------------------------------------------- 18 | // I/O 19 | 20 | static void hal_io_init () { 21 | // NSS and DIO0 are required, DIO1 is required for LoRa, DIO2 for FSK 22 | ASSERT(lmic_pins.nss != LMIC_UNUSED_PIN); 23 | ASSERT(lmic_pins.dio[0] != LMIC_UNUSED_PIN); 24 | ASSERT(lmic_pins.dio[1] != LMIC_UNUSED_PIN || lmic_pins.dio[2] != LMIC_UNUSED_PIN); 25 | 26 | pinMode(lmic_pins.nss, OUTPUT); 27 | if (lmic_pins.rxtx != LMIC_UNUSED_PIN) 28 | pinMode(lmic_pins.rxtx, OUTPUT); 29 | if (lmic_pins.rst != LMIC_UNUSED_PIN) 30 | pinMode(lmic_pins.rst, OUTPUT); 31 | 32 | pinMode(lmic_pins.dio[0], INPUT); 33 | if (lmic_pins.dio[1] != LMIC_UNUSED_PIN) 34 | pinMode(lmic_pins.dio[1], INPUT); 35 | if (lmic_pins.dio[2] != LMIC_UNUSED_PIN) 36 | pinMode(lmic_pins.dio[2], INPUT); 37 | } 38 | 39 | // val == 1 => tx 1 40 | void hal_pin_rxtx (u1_t val) { 41 | if (lmic_pins.rxtx != LMIC_UNUSED_PIN) 42 | digitalWrite(lmic_pins.rxtx, val); 43 | } 44 | 45 | // set radio RST pin to given value (or keep floating!) 46 | void hal_pin_rst (u1_t val) { 47 | if (lmic_pins.rst == LMIC_UNUSED_PIN) 48 | return; 49 | 50 | if(val == 0 || val == 1) { // drive pin 51 | pinMode(lmic_pins.rst, OUTPUT); 52 | digitalWrite(lmic_pins.rst, val); 53 | } else { // keep pin floating 54 | pinMode(lmic_pins.rst, INPUT); 55 | } 56 | } 57 | 58 | static bool dio_states[NUM_DIO] = {0}; 59 | 60 | static void hal_io_check() { 61 | uint8_t i; 62 | for (i = 0; i < NUM_DIO; ++i) { 63 | if (lmic_pins.dio[i] == LMIC_UNUSED_PIN) 64 | continue; 65 | 66 | if (dio_states[i] != digitalRead(lmic_pins.dio[i])) { 67 | dio_states[i] = !dio_states[i]; 68 | if (dio_states[i]) 69 | radio_irq_handler(i); 70 | } 71 | } 72 | } 73 | 74 | // ----------------------------------------------------------------------------- 75 | // SPI 76 | 77 | static const SPISettings settings(10E6, MSBFIRST, SPI_MODE0); 78 | 79 | static void hal_spi_init () { 80 | SPI.begin(); 81 | } 82 | 83 | void hal_pin_nss (u1_t val) { 84 | if (!val) 85 | SPI.beginTransaction(settings); 86 | else 87 | SPI.endTransaction(); 88 | 89 | //Serial.println(val?">>":"<<"); 90 | digitalWrite(lmic_pins.nss, val); 91 | } 92 | 93 | // perform SPI transaction with radio 94 | u1_t hal_spi (u1_t out) { 95 | u1_t res = SPI.transfer(out); 96 | /* 97 | Serial.print(">"); 98 | Serial.print(out, HEX); 99 | Serial.print("<"); 100 | Serial.println(res, HEX); 101 | */ 102 | return res; 103 | } 104 | 105 | // ----------------------------------------------------------------------------- 106 | // TIME 107 | 108 | static void hal_time_init () { 109 | // Nothing to do 110 | } 111 | 112 | u4_t hal_ticks () { 113 | // Because micros() is scaled down in this function, micros() will 114 | // overflow before the tick timer should, causing the tick timer to 115 | // miss a significant part of its values if not corrected. To fix 116 | // this, the "overflow" serves as an overflow area for the micros() 117 | // counter. It consists of three parts: 118 | // - The US_PER_OSTICK upper bits are effectively an extension for 119 | // the micros() counter and are added to the result of this 120 | // function. 121 | // - The next bit overlaps with the most significant bit of 122 | // micros(). This is used to detect micros() overflows. 123 | // - The remaining bits are always zero. 124 | // 125 | // By comparing the overlapping bit with the corresponding bit in 126 | // the micros() return value, overflows can be detected and the 127 | // upper bits are incremented. This is done using some clever 128 | // bitwise operations, to remove the need for comparisons and a 129 | // jumps, which should result in efficient code. By avoiding shifts 130 | // other than by multiples of 8 as much as possible, this is also 131 | // efficient on AVR (which only has 1-bit shifts). 132 | static uint8_t overflow = 0; 133 | 134 | // Scaled down timestamp. The top US_PER_OSTICK_EXPONENT bits are 0, 135 | // the others will be the lower bits of our return value. 136 | uint32_t scaled = micros() >> US_PER_OSTICK_EXPONENT; 137 | // Most significant byte of scaled 138 | uint8_t msb = scaled >> 24; 139 | // Mask pointing to the overlapping bit in msb and overflow. 140 | const uint8_t mask = (1 << (7 - US_PER_OSTICK_EXPONENT)); 141 | // Update overflow. If the overlapping bit is different 142 | // between overflow and msb, it is added to the stored value, 143 | // so the overlapping bit becomes equal again and, if it changed 144 | // from 1 to 0, the upper bits are incremented. 145 | overflow += (msb ^ overflow) & mask; 146 | 147 | // Return the scaled value with the upper bits of stored added. The 148 | // overlapping bit will be equal and the lower bits will be 0, so 149 | // bitwise or is a no-op for them. 150 | return scaled | ((uint32_t)overflow << 24); 151 | 152 | // 0 leads to correct, but overly complex code (it could just return 153 | // micros() unmodified), 8 leaves no room for the overlapping bit. 154 | static_assert(US_PER_OSTICK_EXPONENT > 0 && US_PER_OSTICK_EXPONENT < 8, "Invalid US_PER_OSTICK_EXPONENT value"); 155 | } 156 | 157 | // Returns the number of ticks until time. Negative values indicate that 158 | // time has already passed. 159 | static s4_t delta_time(u4_t time) { 160 | return (s4_t)(time - hal_ticks()); 161 | } 162 | 163 | void hal_waitUntil (u4_t time) { 164 | s4_t delta = delta_time(time); 165 | // From delayMicroseconds docs: Currently, the largest value that 166 | // will produce an accurate delay is 16383. 167 | while (delta > (16000 / US_PER_OSTICK)) { 168 | delay(16); 169 | delta -= (16000 / US_PER_OSTICK); 170 | } 171 | if (delta > 0) 172 | delayMicroseconds(delta * US_PER_OSTICK); 173 | } 174 | 175 | // check and rewind for target time 176 | u1_t hal_checkTimer (u4_t time) { 177 | // No need to schedule wakeup, since we're not sleeping 178 | return delta_time(time) <= 0; 179 | } 180 | 181 | static uint8_t irqlevel = 0; 182 | 183 | void hal_disableIRQs () { 184 | noInterrupts(); 185 | irqlevel++; 186 | } 187 | 188 | void hal_enableIRQs () { 189 | if(--irqlevel == 0) { 190 | interrupts(); 191 | 192 | // Instead of using proper interrupts (which are a bit tricky 193 | // and/or not available on all pins on AVR), just poll the pin 194 | // values. Since os_runloop disables and re-enables interrupts, 195 | // putting this here makes sure we check at least once every 196 | // loop. 197 | // 198 | // As an additional bonus, this prevents the can of worms that 199 | // we would otherwise get for running SPI transfers inside ISRs 200 | hal_io_check(); 201 | } 202 | } 203 | 204 | void hal_sleep () { 205 | // Not implemented 206 | } 207 | 208 | // ----------------------------------------------------------------------------- 209 | 210 | #if defined(LMIC_PRINTF_TO) 211 | static int uart_putchar (char c, FILE *) 212 | { 213 | LMIC_PRINTF_TO.write(c) ; 214 | return 0 ; 215 | } 216 | 217 | void hal_printf_init() { 218 | // create a FILE structure to reference our UART output function 219 | static FILE uartout; 220 | memset(&uartout, 0, sizeof(uartout)); 221 | 222 | // fill in the UART file descriptor with pointer to writer. 223 | fdev_setup_stream (&uartout, uart_putchar, NULL, _FDEV_SETUP_WRITE); 224 | 225 | // The uart is the standard output device STDOUT. 226 | stdout = &uartout ; 227 | } 228 | #endif // defined(LMIC_PRINTF_TO) 229 | 230 | void hal_init () { 231 | // configure radio I/O and interrupt handler 232 | hal_io_init(); 233 | // configure radio SPI 234 | hal_spi_init(); 235 | // configure timer and interrupt handler 236 | hal_time_init(); 237 | #if defined(LMIC_PRINTF_TO) 238 | // printf support 239 | hal_printf_init(); 240 | #endif 241 | } 242 | 243 | void hal_failed (const char *file, u2_t line) { 244 | #if defined(LMIC_FAILURE_TO) 245 | LMIC_FAILURE_TO.println("FAILURE "); 246 | LMIC_FAILURE_TO.print(file); 247 | LMIC_FAILURE_TO.print(':'); 248 | LMIC_FAILURE_TO.println(line); 249 | LMIC_FAILURE_TO.flush(); 250 | #endif 251 | hal_disableIRQs(); 252 | while(1); 253 | } 254 | -------------------------------------------------------------------------------- /lib/LMIC-Arduino_ID852/examples/ttn-abp/ttn-abp.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman 3 | * 4 | * Permission is hereby granted, free of charge, to anyone 5 | * obtaining a copy of this document and accompanying files, 6 | * to do whatever they want with them without any restriction, 7 | * including, but not limited to, copying, modification and redistribution. 8 | * NO WARRANTY OF ANY KIND IS PROVIDED. 9 | * 10 | * This example sends a valid LoRaWAN packet with payload "Hello, 11 | * world!", using frequency and encryption settings matching those of 12 | * the The Things Network. 13 | * 14 | * This uses ABP (Activation-by-personalisation), where a DevAddr and 15 | * Session keys are preconfigured (unlike OTAA, where a DevEUI and 16 | * application key is configured, while the DevAddr and session keys are 17 | * assigned/generated in the over-the-air-activation procedure). 18 | * 19 | * Note: LoRaWAN per sub-band duty-cycle limitation is enforced (1% in 20 | * g1, 0.1% in g2), but not the TTN fair usage policy (which is probably 21 | * violated by this sketch when left running for longer)! 22 | * 23 | * To use this sketch, first register your application and device with 24 | * the things network, to set or generate a DevAddr, NwkSKey and 25 | * AppSKey. Each device should have their own unique values for these 26 | * fields. 27 | * 28 | * Do not forget to define the radio type correctly in config.h. 29 | * 30 | *******************************************************************************/ 31 | 32 | #include 33 | #include 34 | #include 35 | 36 | // LoRaWAN NwkSKey, network session key 37 | // This is the default Semtech key, which is used by the early prototype TTN 38 | // network. 39 | static const PROGMEM u1_t NWKSKEY[16] = { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }; 40 | 41 | // LoRaWAN AppSKey, application session key 42 | // This is the default Semtech key, which is used by the early prototype TTN 43 | // network. 44 | static const u1_t PROGMEM APPSKEY[16] = { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }; 45 | 46 | // LoRaWAN end-device address (DevAddr) 47 | static const u4_t DEVADDR = 0x03FF0001 ; // <-- Change this address for every node! 48 | 49 | // These callbacks are only used in over-the-air activation, so they are 50 | // left empty here (we cannot leave them out completely unless 51 | // DISABLE_JOIN is set in config.h, otherwise the linker will complain). 52 | void os_getArtEui (u1_t* buf) { } 53 | void os_getDevEui (u1_t* buf) { } 54 | void os_getDevKey (u1_t* buf) { } 55 | 56 | static uint8_t mydata[] = "Hello, world!"; 57 | static osjob_t sendjob; 58 | 59 | // Schedule TX every this many seconds (might become longer due to duty 60 | // cycle limitations). 61 | const unsigned TX_INTERVAL = 60; 62 | 63 | // Pin mapping 64 | const lmic_pinmap lmic_pins = { 65 | .nss = 6, 66 | .rxtx = LMIC_UNUSED_PIN, 67 | .rst = 5, 68 | .dio = {2, 3, 4}, 69 | }; 70 | 71 | void onEvent (ev_t ev) { 72 | Serial.print(os_getTime()); 73 | Serial.print(": "); 74 | switch(ev) { 75 | case EV_SCAN_TIMEOUT: 76 | Serial.println(F("EV_SCAN_TIMEOUT")); 77 | break; 78 | case EV_BEACON_FOUND: 79 | Serial.println(F("EV_BEACON_FOUND")); 80 | break; 81 | case EV_BEACON_MISSED: 82 | Serial.println(F("EV_BEACON_MISSED")); 83 | break; 84 | case EV_BEACON_TRACKED: 85 | Serial.println(F("EV_BEACON_TRACKED")); 86 | break; 87 | case EV_JOINING: 88 | Serial.println(F("EV_JOINING")); 89 | break; 90 | case EV_JOINED: 91 | Serial.println(F("EV_JOINED")); 92 | break; 93 | case EV_RFU1: 94 | Serial.println(F("EV_RFU1")); 95 | break; 96 | case EV_JOIN_FAILED: 97 | Serial.println(F("EV_JOIN_FAILED")); 98 | break; 99 | case EV_REJOIN_FAILED: 100 | Serial.println(F("EV_REJOIN_FAILED")); 101 | break; 102 | case EV_TXCOMPLETE: 103 | Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)")); 104 | if (LMIC.txrxFlags & TXRX_ACK) 105 | Serial.println(F("Received ack")); 106 | if (LMIC.dataLen) { 107 | Serial.println(F("Received ")); 108 | Serial.println(LMIC.dataLen); 109 | Serial.println(F(" bytes of payload")); 110 | } 111 | // Schedule next transmission 112 | os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(TX_INTERVAL), do_send); 113 | break; 114 | case EV_LOST_TSYNC: 115 | Serial.println(F("EV_LOST_TSYNC")); 116 | break; 117 | case EV_RESET: 118 | Serial.println(F("EV_RESET")); 119 | break; 120 | case EV_RXCOMPLETE: 121 | // data received in ping slot 122 | Serial.println(F("EV_RXCOMPLETE")); 123 | break; 124 | case EV_LINK_DEAD: 125 | Serial.println(F("EV_LINK_DEAD")); 126 | break; 127 | case EV_LINK_ALIVE: 128 | Serial.println(F("EV_LINK_ALIVE")); 129 | break; 130 | default: 131 | Serial.println(F("Unknown event")); 132 | break; 133 | } 134 | } 135 | 136 | void do_send(osjob_t* j){ 137 | // Check if there is not a current TX/RX job running 138 | if (LMIC.opmode & OP_TXRXPEND) { 139 | Serial.println(F("OP_TXRXPEND, not sending")); 140 | } else { 141 | // Prepare upstream data transmission at the next possible time. 142 | LMIC_setTxData2(1, mydata, sizeof(mydata)-1, 0); 143 | Serial.println(F("Packet queued")); 144 | } 145 | // Next TX is scheduled after TX_COMPLETE event. 146 | } 147 | 148 | void setup() { 149 | Serial.begin(115200); 150 | Serial.println(F("Starting")); 151 | 152 | #ifdef VCC_ENABLE 153 | // For Pinoccio Scout boards 154 | pinMode(VCC_ENABLE, OUTPUT); 155 | digitalWrite(VCC_ENABLE, HIGH); 156 | delay(1000); 157 | #endif 158 | 159 | // LMIC init 160 | os_init(); 161 | // Reset the MAC state. Session and pending data transfers will be discarded. 162 | LMIC_reset(); 163 | 164 | // Set static session parameters. Instead of dynamically establishing a session 165 | // by joining the network, precomputed session parameters are be provided. 166 | #ifdef PROGMEM 167 | // On AVR, these values are stored in flash and only copied to RAM 168 | // once. Copy them to a temporary buffer here, LMIC_setSession will 169 | // copy them into a buffer of its own again. 170 | uint8_t appskey[sizeof(APPSKEY)]; 171 | uint8_t nwkskey[sizeof(NWKSKEY)]; 172 | memcpy_P(appskey, APPSKEY, sizeof(APPSKEY)); 173 | memcpy_P(nwkskey, NWKSKEY, sizeof(NWKSKEY)); 174 | LMIC_setSession (0x1, DEVADDR, nwkskey, appskey); 175 | #else 176 | // If not running an AVR with PROGMEM, just use the arrays directly 177 | LMIC_setSession (0x1, DEVADDR, NWKSKEY, APPSKEY); 178 | #endif 179 | 180 | #if defined(CFG_eu868) 181 | // Set up the channels used by the Things Network, which corresponds 182 | // to the defaults of most gateways. Without this, only three base 183 | // channels from the LoRaWAN specification are used, which certainly 184 | // works, so it is good for debugging, but can overload those 185 | // frequencies, so be sure to configure the full frequency range of 186 | // your network here (unless your network autoconfigures them). 187 | // Setting up channels should happen after LMIC_setSession, as that 188 | // configures the minimal channel set. 189 | // NA-US channels 0-71 are configured automatically 190 | LMIC_setupChannel(0, 868100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band 191 | LMIC_setupChannel(1, 868300000, DR_RANGE_MAP(DR_SF12, DR_SF7B), BAND_CENTI); // g-band 192 | LMIC_setupChannel(2, 868500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band 193 | LMIC_setupChannel(3, 867100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band 194 | LMIC_setupChannel(4, 867300000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band 195 | LMIC_setupChannel(5, 867500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band 196 | LMIC_setupChannel(6, 867700000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band 197 | LMIC_setupChannel(7, 867900000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band 198 | LMIC_setupChannel(8, 868800000, DR_RANGE_MAP(DR_FSK, DR_FSK), BAND_MILLI); // g2-band 199 | // TTN defines an additional channel at 869.525Mhz using SF9 for class B 200 | // devices' ping slots. LMIC does not have an easy way to define set this 201 | // frequency and support for class B is spotty and untested, so this 202 | // frequency is not configured here. 203 | #elif defined(CFG_us915) 204 | // NA-US channels 0-71 are configured automatically 205 | // but only one group of 8 should (a subband) should be active 206 | // TTN recommends the second sub band, 1 in a zero based count. 207 | // https://github.com/TheThingsNetwork/gateway-conf/blob/master/US-global_conf.json 208 | LMIC_selectSubBand(1); 209 | #endif 210 | 211 | // Disable link check validation 212 | LMIC_setLinkCheckMode(0); 213 | 214 | // TTN uses SF9 for its RX2 window. 215 | LMIC.dn2Dr = DR_SF9; 216 | 217 | // Set data rate and transmit power for uplink (note: txpow seems to be ignored by the library) 218 | LMIC_setDrTxpow(DR_SF7,14); 219 | 220 | // Start job 221 | do_send(&sendjob); 222 | } 223 | 224 | void loop() { 225 | os_runloop_once(); 226 | } 227 | -------------------------------------------------------------------------------- /lib/ESP8266_SSD1306_ID562/OLEDDisplayUi.h: -------------------------------------------------------------------------------- 1 | /** 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2018 by ThingPulse, Daniel Eichhorn 5 | * Copyright (c) 2018 by Fabrice Weinberg 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | * 25 | * ThingPulse invests considerable time and money to develop these open source libraries. 26 | * Please support us by buying our products (and not the clones) from 27 | * https://thingpulse.com 28 | * 29 | */ 30 | 31 | #ifndef OLEDDISPLAYUI_h 32 | #define OLEDDISPLAYUI_h 33 | 34 | #include 35 | #include "OLEDDisplay.h" 36 | 37 | //#define DEBUG_OLEDDISPLAYUI(...) Serial.printf( __VA_ARGS__ ) 38 | 39 | #ifndef DEBUG_OLEDDISPLAYUI 40 | #define DEBUG_OLEDDISPLAYUI(...) 41 | #endif 42 | 43 | enum AnimationDirection { 44 | SLIDE_UP, 45 | SLIDE_DOWN, 46 | SLIDE_LEFT, 47 | SLIDE_RIGHT 48 | }; 49 | 50 | enum IndicatorPosition { 51 | TOP, 52 | RIGHT, 53 | BOTTOM, 54 | LEFT 55 | }; 56 | 57 | enum IndicatorDirection { 58 | LEFT_RIGHT, 59 | RIGHT_LEFT 60 | }; 61 | 62 | enum FrameState { 63 | IN_TRANSITION, 64 | FIXED 65 | }; 66 | 67 | 68 | const uint8_t ANIMATION_activeSymbol[] PROGMEM = { 69 | 0x00, 0x18, 0x3c, 0x7e, 0x7e, 0x3c, 0x18, 0x00 70 | }; 71 | 72 | const uint8_t ANIMATION_inactiveSymbol[] PROGMEM = { 73 | 0x00, 0x0, 0x0, 0x18, 0x18, 0x0, 0x0, 0x00 74 | }; 75 | 76 | 77 | // Structure of the UiState 78 | struct OLEDDisplayUiState { 79 | uint64_t lastUpdate = 0; 80 | uint16_t ticksSinceLastStateSwitch = 0; 81 | 82 | FrameState frameState = FIXED; 83 | uint8_t currentFrame = 0; 84 | 85 | bool isIndicatorDrawen = true; 86 | 87 | // Normal = 1, Inverse = -1; 88 | int8_t frameTransitionDirection = 1; 89 | 90 | bool manuelControll = false; 91 | 92 | // Custom data that can be used by the user 93 | void* userData = NULL; 94 | }; 95 | 96 | struct LoadingStage { 97 | const char* process; 98 | void (*callback)(); 99 | }; 100 | 101 | typedef void (*FrameCallback)(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y); 102 | typedef void (*OverlayCallback)(OLEDDisplay *display, OLEDDisplayUiState* state); 103 | typedef void (*LoadingDrawFunction)(OLEDDisplay *display, LoadingStage* stage, uint8_t progress); 104 | 105 | class OLEDDisplayUi { 106 | private: 107 | OLEDDisplay *display; 108 | 109 | // Symbols for the Indicator 110 | IndicatorPosition indicatorPosition = BOTTOM; 111 | IndicatorDirection indicatorDirection = LEFT_RIGHT; 112 | 113 | const uint8_t* activeSymbol = ANIMATION_activeSymbol; 114 | const uint8_t* inactiveSymbol = ANIMATION_inactiveSymbol; 115 | 116 | bool shouldDrawIndicators = true; 117 | 118 | // Values for the Frames 119 | AnimationDirection frameAnimationDirection = SLIDE_RIGHT; 120 | 121 | int8_t lastTransitionDirection = 1; 122 | 123 | uint16_t ticksPerFrame = 151; // ~ 5000ms at 30 FPS 124 | uint16_t ticksPerTransition = 15; // ~ 500ms at 30 FPS 125 | 126 | bool autoTransition = true; 127 | 128 | FrameCallback* frameFunctions; 129 | uint8_t frameCount = 0; 130 | 131 | // Internally used to transition to a specific frame 132 | int8_t nextFrameNumber = -1; 133 | 134 | // Values for Overlays 135 | OverlayCallback* overlayFunctions; 136 | uint8_t overlayCount = 0; 137 | 138 | // Will the Indicator be drawen 139 | // 3 Not drawn in both frames 140 | // 2 Drawn this frame but not next 141 | // 1 Not drown this frame but next 142 | // 0 Not known yet 143 | uint8_t indicatorDrawState = 1; 144 | 145 | // Loading screen 146 | LoadingDrawFunction loadingDrawFunction = [](OLEDDisplay *display, LoadingStage* stage, uint8_t progress) { 147 | display->setTextAlignment(TEXT_ALIGN_CENTER); 148 | display->setFont(ArialMT_Plain_10); 149 | display->drawString(64, 18, stage->process); 150 | display->drawProgressBar(4, 32, 120, 8, progress); 151 | }; 152 | 153 | // UI State 154 | OLEDDisplayUiState state; 155 | 156 | // Bookeeping for update 157 | uint8_t updateInterval = 33; 158 | 159 | uint8_t getNextFrameNumber(); 160 | void drawIndicator(); 161 | void drawFrame(); 162 | void drawOverlays(); 163 | void tick(); 164 | void resetState(); 165 | 166 | public: 167 | 168 | OLEDDisplayUi(OLEDDisplay *display); 169 | 170 | /** 171 | * Initialise the display 172 | */ 173 | void init(); 174 | 175 | /** 176 | * Configure the internal used target FPS 177 | */ 178 | void setTargetFPS(uint8_t fps); 179 | 180 | // Automatic Controll 181 | /** 182 | * Enable automatic transition to next frame after the some time can be configured with `setTimePerFrame` and `setTimePerTransition`. 183 | */ 184 | void enableAutoTransition(); 185 | 186 | /** 187 | * Disable automatic transition to next frame. 188 | */ 189 | void disableAutoTransition(); 190 | 191 | /** 192 | * Set the direction if the automatic transitioning 193 | */ 194 | void setAutoTransitionForwards(); 195 | void setAutoTransitionBackwards(); 196 | 197 | /** 198 | * Set the approx. time a frame is displayed 199 | */ 200 | void setTimePerFrame(uint16_t time); 201 | 202 | /** 203 | * Set the approx. time a transition will take 204 | */ 205 | void setTimePerTransition(uint16_t time); 206 | 207 | // Customize indicator position and style 208 | 209 | /** 210 | * Draw the indicator. 211 | * This is the defaut state for all frames if 212 | * the indicator was hidden on the previous frame 213 | * it will be slided in. 214 | */ 215 | void enableIndicator(); 216 | 217 | /** 218 | * Don't draw the indicator. 219 | * This will slide out the indicator 220 | * when transitioning to the next frame. 221 | */ 222 | void disableIndicator(); 223 | 224 | /** 225 | * Enable drawing of indicators 226 | */ 227 | void enableAllIndicators(); 228 | 229 | /** 230 | * Disable draw of indicators. 231 | */ 232 | void disableAllIndicators(); 233 | 234 | /** 235 | * Set the position of the indicator bar. 236 | */ 237 | void setIndicatorPosition(IndicatorPosition pos); 238 | 239 | /** 240 | * Set the direction of the indicator bar. Defining the order of frames ASCENDING / DESCENDING 241 | */ 242 | void setIndicatorDirection(IndicatorDirection dir); 243 | 244 | /** 245 | * Set the symbol to indicate an active frame in the indicator bar. 246 | */ 247 | void setActiveSymbol(const uint8_t* symbol); 248 | 249 | /** 250 | * Set the symbol to indicate an inactive frame in the indicator bar. 251 | */ 252 | void setInactiveSymbol(const uint8_t* symbol); 253 | 254 | 255 | // Frame settings 256 | 257 | /** 258 | * Configure what animation is used to transition from one frame to another 259 | */ 260 | void setFrameAnimation(AnimationDirection dir); 261 | 262 | /** 263 | * Add frame drawing functions 264 | */ 265 | void setFrames(FrameCallback* frameFunctions, uint8_t frameCount); 266 | 267 | // Overlay 268 | 269 | /** 270 | * Add overlays drawing functions that are draw independent of the Frames 271 | */ 272 | void setOverlays(OverlayCallback* overlayFunctions, uint8_t overlayCount); 273 | 274 | 275 | // Loading animation 276 | /** 277 | * Set the function that will draw each step 278 | * in the loading animation 279 | */ 280 | void setLoadingDrawFunction(LoadingDrawFunction loadingFunction); 281 | 282 | 283 | /** 284 | * Run the loading process 285 | */ 286 | void runLoadingProcess(LoadingStage* stages, uint8_t stagesCount); 287 | 288 | 289 | // Manual Control 290 | void nextFrame(); 291 | void previousFrame(); 292 | 293 | /** 294 | * Switch without transition to frame `frame`. 295 | */ 296 | void switchToFrame(uint8_t frame); 297 | 298 | /** 299 | * Transition to frame `frame`, when the `frame` number is bigger than the current 300 | * frame the forward animation will be used, otherwise the backwards animation is used. 301 | */ 302 | void transitionToFrame(uint8_t frame); 303 | 304 | // State Info 305 | OLEDDisplayUiState* getUiState(); 306 | 307 | int8_t update(); 308 | }; 309 | #endif 310 | -------------------------------------------------------------------------------- /lib/LMIC-Arduino_ID852/src/lmic/oslmic.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014-2015 IBM Corporation. 3 | * All rights reserved. This program and the accompanying materials 4 | * are made available under the terms of the Eclipse Public License v1.0 5 | * which accompanies this distribution, and is available at 6 | * http://www.eclipse.org/legal/epl-v10.html 7 | * 8 | * Contributors: 9 | * IBM Zurich Research Lab - initial API, implementation and documentation 10 | *******************************************************************************/ 11 | 12 | //! \file 13 | #ifndef _oslmic_h_ 14 | #define _oslmic_h_ 15 | 16 | // Dependencies required for the LoRa MAC in C to run. 17 | // These settings can be adapted to the underlying system. 18 | // You should not, however, change the lmic.[hc] 19 | 20 | #include "config.h" 21 | #include 22 | #include 23 | 24 | #ifdef __cplusplus 25 | extern "C"{ 26 | #endif 27 | 28 | //================================================================================ 29 | //================================================================================ 30 | // Target platform as C library 31 | typedef uint8_t bit_t; 32 | typedef uint8_t u1_t; 33 | typedef int8_t s1_t; 34 | typedef uint16_t u2_t; 35 | typedef int16_t s2_t; 36 | typedef uint32_t u4_t; 37 | typedef int32_t s4_t; 38 | typedef unsigned int uint; 39 | typedef const char* str_t; 40 | 41 | #include 42 | #include "hal.h" 43 | #define EV(a,b,c) /**/ 44 | #define DO_DEVDB(field1,field2) /**/ 45 | #if !defined(CFG_noassert) 46 | #define ASSERT(cond) if(!(cond)) hal_failed(__FILE__, __LINE__) 47 | #else 48 | #define ASSERT(cond) /**/ 49 | #endif 50 | 51 | #define os_clearMem(a,b) memset(a,0,b) 52 | #define os_copyMem(a,b,c) memcpy(a,b,c) 53 | 54 | typedef struct osjob_t osjob_t; 55 | typedef struct band_t band_t; 56 | typedef struct chnldef_t chnldef_t; 57 | typedef struct rxsched_t rxsched_t; 58 | typedef struct bcninfo_t bcninfo_t; 59 | typedef const u1_t* xref2cu1_t; 60 | typedef u1_t* xref2u1_t; 61 | #define TYPEDEF_xref2rps_t typedef rps_t* xref2rps_t 62 | #define TYPEDEF_xref2rxsched_t typedef rxsched_t* xref2rxsched_t 63 | #define TYPEDEF_xref2chnldef_t typedef chnldef_t* xref2chnldef_t 64 | #define TYPEDEF_xref2band_t typedef band_t* xref2band_t 65 | #define TYPEDEF_xref2osjob_t typedef osjob_t* xref2osjob_t 66 | 67 | #define SIZEOFEXPR(x) sizeof(x) 68 | 69 | #define ON_LMIC_EVENT(ev) onEvent(ev) 70 | #define DECL_ON_LMIC_EVENT void onEvent(ev_t e) 71 | 72 | extern u4_t AESAUX[]; 73 | extern u4_t AESKEY[]; 74 | #define AESkey ((u1_t*)AESKEY) 75 | #define AESaux ((u1_t*)AESAUX) 76 | #define FUNC_ADDR(func) (&(func)) 77 | 78 | u1_t radio_rand1 (void); 79 | #define os_getRndU1() radio_rand1() 80 | 81 | #define DEFINE_LMIC struct lmic_t LMIC 82 | #define DECLARE_LMIC extern struct lmic_t LMIC 83 | 84 | void radio_init (void); 85 | void radio_irq_handler (u1_t dio); 86 | void os_init (void); 87 | void os_runloop (void); 88 | void os_runloop_once (void); 89 | 90 | //================================================================================ 91 | 92 | 93 | #ifndef RX_RAMPUP 94 | #define RX_RAMPUP (us2osticks(2000)) 95 | #endif 96 | #ifndef TX_RAMPUP 97 | #define TX_RAMPUP (us2osticks(2000)) 98 | #endif 99 | 100 | #ifndef OSTICKS_PER_SEC 101 | #define OSTICKS_PER_SEC 32768 102 | #elif OSTICKS_PER_SEC < 10000 || OSTICKS_PER_SEC > 64516 103 | #error Illegal OSTICKS_PER_SEC - must be in range [10000:64516]. One tick must be 15.5us .. 100us long. 104 | #endif 105 | 106 | typedef s4_t ostime_t; 107 | 108 | #if !HAS_ostick_conv 109 | #define us2osticks(us) ((ostime_t)( ((int64_t)(us) * OSTICKS_PER_SEC) / 1000000)) 110 | #define ms2osticks(ms) ((ostime_t)( ((int64_t)(ms) * OSTICKS_PER_SEC) / 1000)) 111 | #define sec2osticks(sec) ((ostime_t)( (int64_t)(sec) * OSTICKS_PER_SEC)) 112 | #define osticks2ms(os) ((s4_t)(((os)*(int64_t)1000 ) / OSTICKS_PER_SEC)) 113 | #define osticks2us(os) ((s4_t)(((os)*(int64_t)1000000 ) / OSTICKS_PER_SEC)) 114 | // Special versions 115 | #define us2osticksCeil(us) ((ostime_t)( ((int64_t)(us) * OSTICKS_PER_SEC + 999999) / 1000000)) 116 | #define us2osticksRound(us) ((ostime_t)( ((int64_t)(us) * OSTICKS_PER_SEC + 500000) / 1000000)) 117 | #define ms2osticksCeil(ms) ((ostime_t)( ((int64_t)(ms) * OSTICKS_PER_SEC + 999) / 1000)) 118 | #define ms2osticksRound(ms) ((ostime_t)( ((int64_t)(ms) * OSTICKS_PER_SEC + 500) / 1000)) 119 | #endif 120 | 121 | 122 | struct osjob_t; // fwd decl. 123 | typedef void (*osjobcb_t) (struct osjob_t*); 124 | struct osjob_t { 125 | struct osjob_t* next; 126 | ostime_t deadline; 127 | osjobcb_t func; 128 | }; 129 | TYPEDEF_xref2osjob_t; 130 | 131 | 132 | #ifndef HAS_os_calls 133 | 134 | #ifndef os_getDevKey 135 | void os_getDevKey (xref2u1_t buf); 136 | #endif 137 | #ifndef os_getArtEui 138 | void os_getArtEui (xref2u1_t buf); 139 | #endif 140 | #ifndef os_getDevEui 141 | void os_getDevEui (xref2u1_t buf); 142 | #endif 143 | #ifndef os_setCallback 144 | void os_setCallback (xref2osjob_t job, osjobcb_t cb); 145 | #endif 146 | #ifndef os_setTimedCallback 147 | void os_setTimedCallback (xref2osjob_t job, ostime_t time, osjobcb_t cb); 148 | #endif 149 | #ifndef os_clearCallback 150 | void os_clearCallback (xref2osjob_t job); 151 | #endif 152 | #ifndef os_getTime 153 | ostime_t os_getTime (void); 154 | #endif 155 | #ifndef os_getTimeSecs 156 | uint os_getTimeSecs (void); 157 | #endif 158 | #ifndef os_radio 159 | void os_radio (u1_t mode); 160 | #endif 161 | #ifndef os_getBattLevel 162 | u1_t os_getBattLevel (void); 163 | #endif 164 | 165 | #ifndef os_rlsbf4 166 | //! Read 32-bit quantity from given pointer in little endian byte order. 167 | u4_t os_rlsbf4 (xref2cu1_t buf); 168 | #endif 169 | #ifndef os_wlsbf4 170 | //! Write 32-bit quntity into buffer in little endian byte order. 171 | void os_wlsbf4 (xref2u1_t buf, u4_t value); 172 | #endif 173 | #ifndef os_rmsbf4 174 | //! Read 32-bit quantity from given pointer in big endian byte order. 175 | u4_t os_rmsbf4 (xref2cu1_t buf); 176 | #endif 177 | #ifndef os_wmsbf4 178 | //! Write 32-bit quntity into buffer in big endian byte order. 179 | void os_wmsbf4 (xref2u1_t buf, u4_t value); 180 | #endif 181 | #ifndef os_rlsbf2 182 | //! Read 16-bit quantity from given pointer in little endian byte order. 183 | u2_t os_rlsbf2 (xref2cu1_t buf); 184 | #endif 185 | #ifndef os_wlsbf2 186 | //! Write 16-bit quntity into buffer in little endian byte order. 187 | void os_wlsbf2 (xref2u1_t buf, u2_t value); 188 | #endif 189 | 190 | //! Get random number (default impl for u2_t). 191 | #ifndef os_getRndU2 192 | #define os_getRndU2() ((u2_t)((os_getRndU1()<<8)|os_getRndU1())) 193 | #endif 194 | #ifndef os_crc16 195 | u2_t os_crc16 (xref2u1_t d, uint len); 196 | #endif 197 | 198 | #endif // !HAS_os_calls 199 | 200 | // ====================================================================== 201 | // Table support 202 | // These macros for defining a table of constants and retrieving values 203 | // from it makes it easier for other platforms (like AVR) to optimize 204 | // table accesses. 205 | // Use CONST_TABLE() whenever declaring or defining a table, and 206 | // TABLE_GET_xx whenever accessing its values. The actual name of the 207 | // declared variable will be modified to prevent accidental direct 208 | // access. The accessor macros forward to an inline function to allow 209 | // proper type checking of the array element type. 210 | 211 | // Helper to add a prefix to the table name 212 | #define RESOLVE_TABLE(table) constant_table_ ## table 213 | 214 | // Accessors for table elements 215 | #define TABLE_GET_U1(table, index) table_get_u1(RESOLVE_TABLE(table), index) 216 | #define TABLE_GET_S1(table, index) table_get_s1(RESOLVE_TABLE(table), index) 217 | #define TABLE_GET_U2(table, index) table_get_u2(RESOLVE_TABLE(table), index) 218 | #define TABLE_GET_S2(table, index) table_get_s2(RESOLVE_TABLE(table), index) 219 | #define TABLE_GET_U4(table, index) table_get_u4(RESOLVE_TABLE(table), index) 220 | #define TABLE_GET_S4(table, index) table_get_s4(RESOLVE_TABLE(table), index) 221 | #define TABLE_GET_OSTIME(table, index) table_get_ostime(RESOLVE_TABLE(table), index) 222 | #define TABLE_GET_U1_TWODIM(table, index1, index2) table_get_u1(RESOLVE_TABLE(table)[index1], index2) 223 | 224 | #if defined(__AVR__) 225 | #include 226 | // Macro to define the getter functions. This loads data from 227 | // progmem using pgm_read_xx, or accesses memory directly when the 228 | // index is a constant so gcc can optimize it away; 229 | #define TABLE_GETTER(postfix, type, pgm_type) \ 230 | inline type table_get ## postfix(const type *table, size_t index) { \ 231 | if (__builtin_constant_p(table[index])) \ 232 | return table[index]; \ 233 | return pgm_read_ ## pgm_type(&table[index]); \ 234 | } 235 | 236 | TABLE_GETTER(_u1, u1_t, byte); 237 | TABLE_GETTER(_s1, s1_t, byte); 238 | TABLE_GETTER(_u2, u2_t, word); 239 | TABLE_GETTER(_s2, s2_t, word); 240 | TABLE_GETTER(_u4, u4_t, dword); 241 | TABLE_GETTER(_s4, s4_t, dword); 242 | 243 | // This assumes ostime_t is 4 bytes, so error out if it is not 244 | typedef int check_sizeof_ostime_t[(sizeof(ostime_t) == 4) ? 0 : -1]; 245 | TABLE_GETTER(_ostime, ostime_t, dword); 246 | 247 | // For AVR, store constants in PROGMEM, saving on RAM usage 248 | #define CONST_TABLE(type, name) const type PROGMEM RESOLVE_TABLE(name) 249 | 250 | #define lmic_printf(fmt, ...) printf_P(PSTR(fmt), ## __VA_ARGS__) 251 | #else 252 | inline u1_t table_get_u1(const u1_t *table, size_t index) { return table[index]; } 253 | inline s1_t table_get_s1(const s1_t *table, size_t index) { return table[index]; } 254 | inline u2_t table_get_u2(const u2_t *table, size_t index) { return table[index]; } 255 | inline s2_t table_get_s2(const s2_t *table, size_t index) { return table[index]; } 256 | inline u4_t table_get_u4(const u4_t *table, size_t index) { return table[index]; } 257 | inline s4_t table_get_s4(const s4_t *table, size_t index) { return table[index]; } 258 | inline ostime_t table_get_ostime(const ostime_t *table, size_t index) { return table[index]; } 259 | 260 | // Declare a table 261 | #define CONST_TABLE(type, name) const type RESOLVE_TABLE(name) 262 | #define lmic_printf printf 263 | #endif 264 | 265 | // ====================================================================== 266 | // AES support 267 | // !!Keep in sync with lorabase.hpp!! 268 | 269 | #ifndef AES_ENC // if AES_ENC is defined as macro all other values must be too 270 | #define AES_ENC 0x00 271 | #define AES_DEC 0x01 272 | #define AES_MIC 0x02 273 | #define AES_CTR 0x04 274 | #define AES_MICNOAUX 0x08 275 | #endif 276 | #ifndef AESkey // if AESkey is defined as macro all other values must be too 277 | extern xref2u1_t AESkey; 278 | extern xref2u1_t AESaux; 279 | #endif 280 | #ifndef os_aes 281 | u4_t os_aes (u1_t mode, xref2u1_t buf, u2_t len); 282 | #endif 283 | 284 | #ifdef __cplusplus 285 | } // extern "C" 286 | #endif 287 | 288 | #endif // _oslmic_h_ 289 | -------------------------------------------------------------------------------- /lib/ESP8266_SSD1306_ID562/OLEDDisplay.h: -------------------------------------------------------------------------------- 1 | /** 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2018 by ThingPulse, Daniel Eichhorn 5 | * Copyright (c) 2018 by Fabrice Weinberg 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | * 25 | * ThingPulse invests considerable time and money to develop these open source libraries. 26 | * Please support us by buying our products (and not the clones) from 27 | * https://thingpulse.com 28 | * 29 | */ 30 | 31 | #ifndef OLEDDISPLAY_h 32 | #define OLEDDISPLAY_h 33 | 34 | #include 35 | #include "OLEDDisplayFonts.h" 36 | 37 | //#define DEBUG_OLEDDISPLAY(...) Serial.printf( __VA_ARGS__ ) 38 | 39 | #ifndef DEBUG_OLEDDISPLAY 40 | #define DEBUG_OLEDDISPLAY(...) 41 | #endif 42 | 43 | // Use DOUBLE BUFFERING by default 44 | #ifndef OLEDDISPLAY_REDUCE_MEMORY 45 | #define OLEDDISPLAY_DOUBLE_BUFFER 46 | #endif 47 | 48 | // Header Values 49 | #define JUMPTABLE_BYTES 4 50 | 51 | #define JUMPTABLE_LSB 1 52 | #define JUMPTABLE_SIZE 2 53 | #define JUMPTABLE_WIDTH 3 54 | #define JUMPTABLE_START 4 55 | 56 | #define WIDTH_POS 0 57 | #define HEIGHT_POS 1 58 | #define FIRST_CHAR_POS 2 59 | #define CHAR_NUM_POS 3 60 | 61 | 62 | // Display commands 63 | #define CHARGEPUMP 0x8D 64 | #define COLUMNADDR 0x21 65 | #define COMSCANDEC 0xC8 66 | #define COMSCANINC 0xC0 67 | #define DISPLAYALLON 0xA5 68 | #define DISPLAYALLON_RESUME 0xA4 69 | #define DISPLAYOFF 0xAE 70 | #define DISPLAYON 0xAF 71 | #define EXTERNALVCC 0x1 72 | #define INVERTDISPLAY 0xA7 73 | #define MEMORYMODE 0x20 74 | #define NORMALDISPLAY 0xA6 75 | #define PAGEADDR 0x22 76 | #define SEGREMAP 0xA0 77 | #define SETCOMPINS 0xDA 78 | #define SETCONTRAST 0x81 79 | #define SETDISPLAYCLOCKDIV 0xD5 80 | #define SETDISPLAYOFFSET 0xD3 81 | #define SETHIGHCOLUMN 0x10 82 | #define SETLOWCOLUMN 0x00 83 | #define SETMULTIPLEX 0xA8 84 | #define SETPRECHARGE 0xD9 85 | #define SETSEGMENTREMAP 0xA1 86 | #define SETSTARTLINE 0x40 87 | #define SETVCOMDETECT 0xDB 88 | #define SWITCHCAPVCC 0x2 89 | 90 | #ifndef _swap_int16_t 91 | #define _swap_int16_t(a, b) { int16_t t = a; a = b; b = t; } 92 | #endif 93 | 94 | enum OLEDDISPLAY_COLOR { 95 | BLACK = 0, 96 | WHITE = 1, 97 | INVERSE = 2 98 | }; 99 | 100 | enum OLEDDISPLAY_TEXT_ALIGNMENT { 101 | TEXT_ALIGN_LEFT = 0, 102 | TEXT_ALIGN_RIGHT = 1, 103 | TEXT_ALIGN_CENTER = 2, 104 | TEXT_ALIGN_CENTER_BOTH = 3 105 | }; 106 | 107 | 108 | enum OLEDDISPLAY_GEOMETRY { 109 | GEOMETRY_128_64 = 0, 110 | GEOMETRY_128_32 = 1 111 | }; 112 | 113 | typedef byte (*FontTableLookupFunction)(const byte ch); 114 | 115 | 116 | class OLEDDisplay : public Print { 117 | 118 | public: 119 | virtual ~OLEDDisplay(); 120 | 121 | const uint16_t width(void) const { return displayWidth; }; 122 | const uint16_t height(void) const { return displayHeight; }; 123 | 124 | // Initialize the display 125 | bool init(); 126 | 127 | // Free the memory used by the display 128 | void end(); 129 | 130 | // Cycle through the initialization 131 | void resetDisplay(void); 132 | 133 | /* Drawing functions */ 134 | // Sets the color of all pixel operations 135 | void setColor(OLEDDISPLAY_COLOR color); 136 | 137 | // Returns the current color. 138 | OLEDDISPLAY_COLOR getColor(); 139 | 140 | // Draw a pixel at given position 141 | void setPixel(int16_t x, int16_t y); 142 | 143 | // Draw a line from position 0 to position 1 144 | void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1); 145 | 146 | // Draw the border of a rectangle at the given location 147 | void drawRect(int16_t x, int16_t y, int16_t width, int16_t height); 148 | 149 | // Fill the rectangle 150 | void fillRect(int16_t x, int16_t y, int16_t width, int16_t height); 151 | 152 | // Draw the border of a circle 153 | void drawCircle(int16_t x, int16_t y, int16_t radius); 154 | 155 | // Draw all Quadrants specified in the quads bit mask 156 | void drawCircleQuads(int16_t x0, int16_t y0, int16_t radius, uint8_t quads); 157 | 158 | // Fill circle 159 | void fillCircle(int16_t x, int16_t y, int16_t radius); 160 | 161 | // Draw a line horizontally 162 | void drawHorizontalLine(int16_t x, int16_t y, int16_t length); 163 | 164 | // Draw a line vertically 165 | void drawVerticalLine(int16_t x, int16_t y, int16_t length); 166 | 167 | // Draws a rounded progress bar with the outer dimensions given by width and height. Progress is 168 | // a unsigned byte value between 0 and 100 169 | void drawProgressBar(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t progress); 170 | 171 | // Draw a bitmap in the internal image format 172 | void drawFastImage(int16_t x, int16_t y, int16_t width, int16_t height, const uint8_t *image); 173 | 174 | // Draw a XBM 175 | void drawXbm(int16_t x, int16_t y, int16_t width, int16_t height, const uint8_t *xbm); 176 | 177 | /* Text functions */ 178 | 179 | // Draws a string at the given location 180 | void drawString(int16_t x, int16_t y, String text); 181 | 182 | // Draws a String with a maximum width at the given location. 183 | // If the given String is wider than the specified width 184 | // The text will be wrapped to the next line at a space or dash 185 | void drawStringMaxWidth(int16_t x, int16_t y, uint16_t maxLineWidth, String text); 186 | 187 | // Returns the width of the const char* with the current 188 | // font settings 189 | uint16_t getStringWidth(const char* text, uint16_t length); 190 | 191 | // Convencience method for the const char version 192 | uint16_t getStringWidth(String text); 193 | 194 | // Specifies relative to which anchor point 195 | // the text is rendered. Available constants: 196 | // TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER, TEXT_ALIGN_RIGHT, TEXT_ALIGN_CENTER_BOTH 197 | void setTextAlignment(OLEDDISPLAY_TEXT_ALIGNMENT textAlignment); 198 | 199 | // Sets the current font. Available default fonts 200 | // ArialMT_Plain_10, ArialMT_Plain_16, ArialMT_Plain_24 201 | void setFont(const uint8_t *fontData); 202 | 203 | // Set the function that will convert utf-8 to font table index 204 | void setFontTableLookupFunction(FontTableLookupFunction function); 205 | 206 | /* Display functions */ 207 | 208 | // Turn the display on 209 | void displayOn(void); 210 | 211 | // Turn the display offs 212 | void displayOff(void); 213 | 214 | // Inverted display mode 215 | void invertDisplay(void); 216 | 217 | // Normal display mode 218 | void normalDisplay(void); 219 | 220 | // Set display contrast 221 | // really low brightness & contrast: contrast = 10, precharge = 5, comdetect = 0 222 | // normal brightness & contrast: contrast = 100 223 | void setContrast(uint8_t contrast, uint8_t precharge = 241, uint8_t comdetect = 64); 224 | 225 | // Reset display rotation or mirroring 226 | void resetOrientation(); 227 | 228 | // Turn the display upside down 229 | void flipScreenVertically(); 230 | 231 | // Mirror the display (to be used in a mirror or as a projector) 232 | void mirrorScreen(); 233 | 234 | // Write the buffer to the display memory 235 | virtual void display(void) = 0; 236 | 237 | // Clear the local pixel buffer 238 | void clear(void); 239 | 240 | // Log buffer implementation 241 | 242 | // This will define the lines and characters you can 243 | // print to the screen. When you exeed the buffer size (lines * chars) 244 | // the output may be truncated due to the size constraint. 245 | bool setLogBuffer(uint16_t lines, uint16_t chars); 246 | 247 | // Draw the log buffer at position (x, y) 248 | void drawLogBuffer(uint16_t x, uint16_t y); 249 | 250 | // Get screen geometry 251 | uint16_t getWidth(void); 252 | uint16_t getHeight(void); 253 | 254 | // Implement needed function to be compatible with Print class 255 | size_t write(uint8_t c); 256 | size_t write(const char* s); 257 | 258 | uint8_t *buffer = NULL; 259 | 260 | #ifdef OLEDDISPLAY_DOUBLE_BUFFER 261 | uint8_t *buffer_back = NULL; 262 | #endif 263 | 264 | protected: 265 | 266 | OLEDDISPLAY_GEOMETRY geometry = GEOMETRY_128_64; 267 | 268 | uint16_t displayWidth = 128; 269 | uint16_t displayHeight = 64; 270 | uint16_t displayBufferSize = 1024; 271 | 272 | // Set the correct height, width and buffer for the geometry 273 | void setGeometry(OLEDDISPLAY_GEOMETRY g); 274 | 275 | OLEDDISPLAY_TEXT_ALIGNMENT textAlignment = TEXT_ALIGN_LEFT; 276 | OLEDDISPLAY_COLOR color = WHITE; 277 | 278 | const uint8_t *fontData = ArialMT_Plain_10; 279 | 280 | // State values for logBuffer 281 | uint16_t logBufferSize = 0; 282 | uint16_t logBufferFilled = 0; 283 | uint16_t logBufferLine = 0; 284 | uint16_t logBufferMaxLines = 0; 285 | char *logBuffer = NULL; 286 | 287 | // Send a command to the display (low level function) 288 | virtual void sendCommand(uint8_t com) {(void)com;}; 289 | 290 | // Connect to the display 291 | virtual bool connect() { return false; }; 292 | 293 | // Send all the init commands 294 | void sendInitCommands(); 295 | 296 | // converts utf8 characters to extended ascii 297 | char* utf8ascii(String s); 298 | 299 | void inline drawInternal(int16_t xMove, int16_t yMove, int16_t width, int16_t height, const uint8_t *data, uint16_t offset, uint16_t bytesInData) __attribute__((always_inline)); 300 | 301 | void drawStringInternal(int16_t xMove, int16_t yMove, char* text, uint16_t textLength, uint16_t textWidth); 302 | 303 | // UTF-8 to font table index converter 304 | // Code form http://playground.arduino.cc/Main/Utf8ascii 305 | FontTableLookupFunction fontTableLookupFunction = [](const byte ch) { 306 | static uint8_t LASTCHAR; 307 | 308 | if (ch < 128) { // Standard ASCII-set 0..0x7F handling 309 | LASTCHAR = 0; 310 | return ch; 311 | } 312 | 313 | uint8_t last = LASTCHAR; // get last char 314 | LASTCHAR = ch; 315 | 316 | switch (last) { // conversion depnding on first UTF8-character 317 | case 0xC2: return (uint8_t) ch; 318 | case 0xC3: return (uint8_t) (ch | 0xC0); 319 | case 0x82: if (ch == 0xAC) return (uint8_t) 0x80; // special case Euro-symbol 320 | } 321 | 322 | return (uint8_t) 0; // otherwise: return zero, if character has to be ignored 323 | }; 324 | }; 325 | 326 | #endif 327 | -------------------------------------------------------------------------------- /lib/LMIC-Arduino_ID852/src/aes/ideetron/AES-128_V10.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************************** 2 | #if defined(USE_IDEETRON_AES) 3 | * Copyright 2015, 2016 Ideetron B.V. 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | ******************************************************************************************/ 18 | /****************************************************************************************** 19 | * 20 | * File: AES-128_V10.cpp 21 | * Author: Gerben den Hartog 22 | * Compagny: Ideetron B.V. 23 | * Website: http://www.ideetron.nl/LoRa 24 | * E-mail: info@ideetron.nl 25 | ******************************************************************************************/ 26 | /**************************************************************************************** 27 | * 28 | * Created on: 20-10-2015 29 | * Supported Hardware: ID150119-02 Nexus board with RFM95 30 | * 31 | * Firmware Version 1.0 32 | * First version 33 | ****************************************************************************************/ 34 | 35 | // This file was taken from 36 | // https://github.com/Ideetron/RFM95W_Nexus/tree/master/LoRaWAN_V31 for 37 | // use with LMIC. It was only cosmetically modified: 38 | // - AES_Encrypt was renamed to lmic_aes_encrypt. 39 | // - All other functions and variables were made static 40 | // - Tabs were converted to 2 spaces 41 | // - An #include and #if guard was added 42 | // - S_Table is now stored in PROGMEM 43 | 44 | #include "../../lmic/oslmic.h" 45 | 46 | #if defined(USE_IDEETRON_AES) 47 | 48 | /* 49 | ******************************************************************************************** 50 | * Global Variables 51 | ******************************************************************************************** 52 | */ 53 | 54 | static unsigned char State[4][4]; 55 | 56 | static CONST_TABLE(unsigned char, S_Table)[16][16] = { 57 | {0x63,0x7C,0x77,0x7B,0xF2,0x6B,0x6F,0xC5,0x30,0x01,0x67,0x2B,0xFE,0xD7,0xAB,0x76}, 58 | {0xCA,0x82,0xC9,0x7D,0xFA,0x59,0x47,0xF0,0xAD,0xD4,0xA2,0xAF,0x9C,0xA4,0x72,0xC0}, 59 | {0xB7,0xFD,0x93,0x26,0x36,0x3F,0xF7,0xCC,0x34,0xA5,0xE5,0xF1,0x71,0xD8,0x31,0x15}, 60 | {0x04,0xC7,0x23,0xC3,0x18,0x96,0x05,0x9A,0x07,0x12,0x80,0xE2,0xEB,0x27,0xB2,0x75}, 61 | {0x09,0x83,0x2C,0x1A,0x1B,0x6E,0x5A,0xA0,0x52,0x3B,0xD6,0xB3,0x29,0xE3,0x2F,0x84}, 62 | {0x53,0xD1,0x00,0xED,0x20,0xFC,0xB1,0x5B,0x6A,0xCB,0xBE,0x39,0x4A,0x4C,0x58,0xCF}, 63 | {0xD0,0xEF,0xAA,0xFB,0x43,0x4D,0x33,0x85,0x45,0xF9,0x02,0x7F,0x50,0x3C,0x9F,0xA8}, 64 | {0x51,0xA3,0x40,0x8F,0x92,0x9D,0x38,0xF5,0xBC,0xB6,0xDA,0x21,0x10,0xFF,0xF3,0xD2}, 65 | {0xCD,0x0C,0x13,0xEC,0x5F,0x97,0x44,0x17,0xC4,0xA7,0x7E,0x3D,0x64,0x5D,0x19,0x73}, 66 | {0x60,0x81,0x4F,0xDC,0x22,0x2A,0x90,0x88,0x46,0xEE,0xB8,0x14,0xDE,0x5E,0x0B,0xDB}, 67 | {0xE0,0x32,0x3A,0x0A,0x49,0x06,0x24,0x5C,0xC2,0xD3,0xAC,0x62,0x91,0x95,0xE4,0x79}, 68 | {0xE7,0xC8,0x37,0x6D,0x8D,0xD5,0x4E,0xA9,0x6C,0x56,0xF4,0xEA,0x65,0x7A,0xAE,0x08}, 69 | {0xBA,0x78,0x25,0x2E,0x1C,0xA6,0xB4,0xC6,0xE8,0xDD,0x74,0x1F,0x4B,0xBD,0x8B,0x8A}, 70 | {0x70,0x3E,0xB5,0x66,0x48,0x03,0xF6,0x0E,0x61,0x35,0x57,0xB9,0x86,0xC1,0x1D,0x9E}, 71 | {0xE1,0xF8,0x98,0x11,0x69,0xD9,0x8E,0x94,0x9B,0x1E,0x87,0xE9,0xCE,0x55,0x28,0xDF}, 72 | {0x8C,0xA1,0x89,0x0D,0xBF,0xE6,0x42,0x68,0x41,0x99,0x2D,0x0F,0xB0,0x54,0xBB,0x16} 73 | }; 74 | 75 | extern "C" void lmic_aes_encrypt(unsigned char *Data, unsigned char *Key); 76 | static void AES_Add_Round_Key(unsigned char *Round_Key); 77 | static unsigned char AES_Sub_Byte(unsigned char Byte); 78 | static void AES_Shift_Rows(); 79 | static void AES_Mix_Collums(); 80 | static void AES_Calculate_Round_Key(unsigned char Round, unsigned char *Round_Key); 81 | static void Send_State(); 82 | 83 | /* 84 | ***************************************************************************************** 85 | * Description : Function for encrypting data using AES-128 86 | * 87 | * Arguments : *Data Data to encrypt is a 16 byte long arry 88 | * *Key Key to encrypt data with is a 16 byte long arry 89 | ***************************************************************************************** 90 | */ 91 | void lmic_aes_encrypt(unsigned char *Data, unsigned char *Key) 92 | { 93 | unsigned char i; 94 | unsigned char Row,Collum; 95 | unsigned char Round = 0x00; 96 | unsigned char Round_Key[16]; 97 | 98 | //Copy input to State arry 99 | for(Collum = 0; Collum < 4; Collum++) 100 | { 101 | for(Row = 0; Row < 4; Row++) 102 | { 103 | State[Row][Collum] = Data[Row + (4*Collum)]; 104 | } 105 | } 106 | 107 | //Copy key to round key 108 | for(i = 0; i < 16; i++) 109 | { 110 | Round_Key[i] = Key[i]; 111 | } 112 | 113 | //Add round key 114 | AES_Add_Round_Key(Round_Key); 115 | 116 | //Preform 9 full rounds 117 | for(Round = 1; Round < 10; Round++) 118 | { 119 | //Preform Byte substitution with S table 120 | for(Collum = 0; Collum < 4; Collum++) 121 | { 122 | for(Row = 0; Row < 4; Row++) 123 | { 124 | State[Row][Collum] = AES_Sub_Byte(State[Row][Collum]); 125 | } 126 | } 127 | 128 | //Preform Row Shift 129 | AES_Shift_Rows(); 130 | 131 | //Mix Collums 132 | AES_Mix_Collums(); 133 | 134 | //Calculate new round key 135 | AES_Calculate_Round_Key(Round,Round_Key); 136 | 137 | //Add round key 138 | AES_Add_Round_Key(Round_Key); 139 | } 140 | 141 | //Last round whitout mix collums 142 | //Preform Byte substitution with S table 143 | for(Collum = 0; Collum < 4; Collum++) 144 | { 145 | for(Row = 0; Row < 4; Row++) 146 | { 147 | State[Row][Collum] = AES_Sub_Byte(State[Row][Collum]); 148 | } 149 | } 150 | 151 | //Shift rows 152 | AES_Shift_Rows(); 153 | 154 | //Calculate new round key 155 | AES_Calculate_Round_Key(Round,Round_Key); 156 | 157 | //Add round Key 158 | AES_Add_Round_Key(Round_Key); 159 | 160 | //Copy the State into the data array 161 | for(Collum = 0; Collum < 4; Collum++) 162 | { 163 | for(Row = 0; Row < 4; Row++) 164 | { 165 | Data[Row + (4*Collum)] = State[Row][Collum]; 166 | } 167 | } 168 | 169 | } 170 | 171 | /* 172 | ***************************************************************************************** 173 | * Description : Function that add's the round key for the current round 174 | * 175 | * Arguments : *Round_Key 16 byte long array holding the Round Key 176 | ***************************************************************************************** 177 | */ 178 | static void AES_Add_Round_Key(unsigned char *Round_Key) 179 | { 180 | unsigned char Row,Collum; 181 | 182 | for(Collum = 0; Collum < 4; Collum++) 183 | { 184 | for(Row = 0; Row < 4; Row++) 185 | { 186 | State[Row][Collum] = State[Row][Collum] ^ Round_Key[Row + (4*Collum)]; 187 | } 188 | } 189 | } 190 | 191 | /* 192 | ***************************************************************************************** 193 | * Description : Function that substitutes a byte with a byte from the S_Table 194 | * 195 | * Arguments : Byte The byte that will be substituted 196 | * 197 | * Return : The return is the found byte in the S_Table 198 | ***************************************************************************************** 199 | */ 200 | static unsigned char AES_Sub_Byte(unsigned char Byte) 201 | { 202 | unsigned char S_Row,S_Collum; 203 | unsigned char S_Byte; 204 | 205 | //Split byte up in Row and Collum 206 | S_Row = ((Byte >> 4) & 0x0F); 207 | S_Collum = (Byte & 0x0F); 208 | 209 | //Find the correct byte in the S_Table 210 | S_Byte = TABLE_GET_U1_TWODIM(S_Table, S_Row, S_Collum); 211 | 212 | return S_Byte; 213 | } 214 | 215 | /* 216 | ***************************************************************************************** 217 | * Description : Function that preforms the shift row operation described in the AES standard 218 | ***************************************************************************************** 219 | */ 220 | static void AES_Shift_Rows() 221 | { 222 | unsigned char Buffer; 223 | 224 | //Row 0 doesn't change 225 | 226 | //Shift Row 1 one left 227 | //Store firt byte in buffer 228 | Buffer = State[1][0]; 229 | //Shift all bytes 230 | State[1][0] = State[1][1]; 231 | State[1][1] = State[1][2]; 232 | State[1][2] = State[1][3]; 233 | State[1][3] = Buffer; 234 | 235 | //Shift row 2 two left 236 | Buffer = State[2][0]; 237 | State[2][0] = State[2][2]; 238 | State[2][2] = Buffer; 239 | Buffer = State[2][1]; 240 | State[2][1] = State[2][3]; 241 | State[2][3] = Buffer; 242 | 243 | //Shift row 3 three left 244 | Buffer = State[3][3]; 245 | State[3][3] = State[3][2]; 246 | State[3][2] = State[3][1]; 247 | State[3][1] = State[3][0]; 248 | State[3][0] = Buffer; 249 | } 250 | 251 | /* 252 | ***************************************************************************************** 253 | * Description : Function that preforms the Mix Collums operation described in the AES standard 254 | ***************************************************************************************** 255 | */ 256 | static void AES_Mix_Collums() 257 | { 258 | unsigned char Row,Collum; 259 | unsigned char a[4], b[4]; 260 | for(Collum = 0; Collum < 4; Collum++) 261 | { 262 | for(Row = 0; Row < 4; Row++) 263 | { 264 | a[Row] = State[Row][Collum]; 265 | b[Row] = (State[Row][Collum] << 1); 266 | 267 | if((State[Row][Collum] & 0x80) == 0x80) 268 | { 269 | b[Row] = b[Row] ^ 0x1B; 270 | } 271 | } 272 | State[0][Collum] = b[0] ^ a[1] ^ b[1] ^ a[2] ^ a[3]; 273 | State[1][Collum] = a[0] ^ b[1] ^ a[2] ^ b[2] ^ a[3]; 274 | State[2][Collum] = a[0] ^ a[1] ^ b[2] ^ a[3] ^ b[3]; 275 | State[3][Collum] = a[0] ^ b[0] ^ a[1] ^ a[2] ^ b[3]; 276 | } 277 | } 278 | 279 | /* 280 | ***************************************************************************************** 281 | * Description : Function that calculaties the round key for the current round 282 | * 283 | * Arguments : Round Number of current Round 284 | * *Round_Key 16 byte long array holding the Round Key 285 | ***************************************************************************************** 286 | */ 287 | static void AES_Calculate_Round_Key(unsigned char Round, unsigned char *Round_Key) 288 | { 289 | unsigned char i,j; 290 | unsigned char b; 291 | unsigned char Temp[4]; 292 | unsigned char Buffer; 293 | unsigned char Rcon; 294 | 295 | //Calculate first Temp 296 | //Copy laste byte from previous key 297 | for(i = 0; i < 4; i++) 298 | { 299 | Temp[i] = Round_Key[i+12]; 300 | } 301 | 302 | //Rotate Temp 303 | Buffer = Temp[0]; 304 | Temp[0] = Temp[1]; 305 | Temp[1] = Temp[2]; 306 | Temp[2] = Temp[3]; 307 | Temp[3] = Buffer; 308 | 309 | //Substitute Temp 310 | for(i = 0; i < 4; i++) 311 | { 312 | Temp[i] = AES_Sub_Byte(Temp[i]); 313 | } 314 | 315 | //Calculate Rcon 316 | Rcon = 0x01; 317 | while(Round != 1) 318 | { 319 | b = Rcon & 0x80; 320 | Rcon = Rcon << 1; 321 | if(b == 0x80) 322 | { 323 | Rcon = Rcon ^ 0x1b; 324 | } 325 | Round--; 326 | } 327 | 328 | //XOR Rcon 329 | Temp[0] = Temp[0] ^ Rcon; 330 | 331 | //Calculate new key 332 | for(i = 0; i < 4; i++) 333 | { 334 | for(j = 0; j < 4; j++) 335 | { 336 | Round_Key[j + (4*i)] = Round_Key[j + (4*i)] ^ Temp[j]; 337 | Temp[j] = Round_Key[j + (4*i)]; 338 | } 339 | } 340 | } 341 | 342 | #endif // defined(USE_IDEETRON_AES) 343 | --------------------------------------------------------------------------------