Skip to content

Commit

Permalink
Merge pull request #7 from jkittley/serial-only
Browse files Browse the repository at this point in the history
Device updates and new docs
  • Loading branch information
jkittley committed Mar 31, 2018
2 parents 34b4663 + 4d2ec23 commit 04eb63f
Show file tree
Hide file tree
Showing 32 changed files with 959 additions and 270 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ old/
*.pyc
server/data/tinydb/*.json
server/data/*.db
server/data/*.log
backups/
docs/build/
docs/make.bat
Expand All @@ -12,4 +13,6 @@ server/test/.pytest_cache/
server/.pytest_cache/

device/arduino/BLE
device/arduino/RFM69
device/arduino/RFM69

.vscode/
10 changes: 6 additions & 4 deletions device/readme.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Little Sense - Device
This folder contains code for various platforms and communication channels. Each folder contains instructions and the required part to setup a device to send sensor readings to the [server](/server/). Full documentation can be found at http://littlesense.readthedocs.io/.
# LittleSense - Device
This folder contains code for various platforms and communication channels. Each folder contains instructions and the required part to setup a device to send sensor readings to the [server](/server/). Full documentation for setting up LittleSense can be found at http://littlesense.readthedocs.io/.

## Examples
- [Arduino Basic Wifi](arduino/basic/)
- More soon
- [Wifi Test](wifi_test/): Generates data every few seconds and sends it to the servers RESTful API via wifi.
- [Serial Test](serial_test/): Generates data every few seconds and sends it to the servers Serial port via USB.
- [RFM69](rfm69/): Gateway and Sensor node.

Binary file added device/res/RFM69_overview.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
256 changes: 256 additions & 0 deletions device/rfm69/gateway/gateway.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
// **********************************************************************************
//
// RFM69 <--> Serial Gateway
//
// This cript acts as an interface between the LittleSense Serial port and the RFM69
// Radio. Because radios such as the RFM69 need to keep the packet length to a minimum
// you must edit this script to translate the RFM69 packet data into JSON. Don't worry
// this script has an example. In addition, the script translates serial messages set
// from the server and transmits them to devices.
//
// Note: Because it is expected that the serial output is going to be read by the
// server. Start all messages with a # and they will be ignored.
//
// **********************************************************************************

#include <RFM69.h> //get it here: https://www.github.com/lowpowerlab/rfm69
#include <RFM69_ATC.h> //get it here: https://www.github.com/lowpowerlab/rfm69
#include <SPI.h> //included with Arduino IDE install (www.arduino.cc)
#include <ArduinoJson.h> //https://arduinojson.org/d

// Node and network config
#define NODEID 1 // The ID of this node (must be different for every node on network)
#define NETWORKID 100 // The network ID

// Are you using the RFM69 Wing? Uncomment if you are.
#define USING_RFM69_WING

// The transmision frequency of the baord. Change as needed.
#define FREQUENCY RF69_433MHZ //RF69_868MHZ // RF69_915MHZ

// An encryption key. Must be the same 16 characters on all nodes. Comment out to disable
#define ENCRYPTKEY "sampleEncryptKey"

// Uncomment if this board is the RFM69HW/HCW not the RFM69W/CW
#define IS_RFM69HW_HCW

// Uncomment to enable auto transmission control - adjusts power to save battery
#define ENABLE_ATC

// Serial board rate
#define SERIAL_BAUD 115200

// Which LED
#define LED LED_BUILTIN

// Board and radio specific config - You should not need to edit
#if defined (__AVR_ATmega32U4__) && defined (USING_RFM69_WING)
#define RF69_SPI_CS 10
#define RF69_RESET 11
#define RF69_IRQ_PIN 2
#define RF69_IRQ_NUM digitalPinToInterrupt(RF69_IRQ_PIN)
#elif defined (__AVR_ATmega32U4__)
#define RF69_RESET 4
#define RF69_SPI_CS 8
#define RF69_IRQ_PIN 7
#define RF69_IRQ_NUM 4
#elif defined(ARDUINO_SAMD_FEATHER_M0) && defined (USING_RFM69_WING)
#define RF69_RESET 11
#define RF69_SPI_CS 10
#define RF69_IRQ_PIN 6
#define RF69_IRQ_NUM digitalPinToInterrupt(RF69_IRQ_PIN)
#elif defined(ARDUINO_SAMD_FEATHER_M0)
#define RF69_RESET 4
#define RF69_SPI_CS 8
#define RF69_IRQ_PIN 3
#define RF69_IRQ_NUM 3
#endif


// Create Radio
#ifdef ENABLE_ATC
RFM69_ATC radio(RF69_SPI_CS, RF69_IRQ_PIN, false, RF69_IRQ_NUM);
#else
RFM69 radio(RF69_SPI_CS, RF69_IRQ_PIN, false, RF69_IRQ_NUM);
#endif

//set to 'true' to sniff all packets on the same network
bool promiscuousMode = false;

// Setup
void setup() {
Serial.begin(SERIAL_BAUD);

// Wait for serial port to connect before anything starts
while (!Serial) {
;
}

// Reset the radio
resetRadio();

// Initialize the radio
radio.initialize(FREQUENCY,NODEID,NETWORKID);
#ifdef IS_RFM69HW_HCW
radio.setHighPower(); //must include this only for RFM69HW/HCW!
#endif
#ifdef ENCRYPTKEY
radio.encrypt(ENCRYPTKEY);
#endif
radio.promiscuous(promiscuousMode);

// Show debug info
printDebugInfo();
}

// Define payload
typedef struct {
char command[20]; // command
uint8_t battery; // Battery voltage
uint8_t volume; // Volume
uint8_t rssi; // RSSI as seen by node
} Payload;
Payload payload;

// Main loop
void loop() {

// Process any serial input
if (Serial.available() > 0) {

String input = Serial.readString();
if (input == 'd') {
printDebugInfo();
}

if (input.toInt() > 0) {
char buff[] = "ShowYourSelf";

Serial.print("# Asking Node "); Serial.print(String(input).toInt()); Serial.println(" to show itself");

if (radio.sendWithRetry(String(input).toInt(), buff, sizeof(buff))) {
Serial.println(" Acknoledgment received!");
} else {
Serial.println(" No Acknoledgment after retries");
}
}
}

// Process packets received
if (radio.receiveDone()) {

Serial.print("# sender: "); Serial.println(radio.SENDERID, DEC);
Serial.print("# target "); Serial.println(radio.TARGETID, DEC);
Serial.print("# Data length: "); Serial.println(radio.DATALEN);
Serial.print("# RX_RSSI:"); Serial.println(radio.RSSI);

if (radio.DATALEN != sizeof(Payload)) {
Serial.print("# Invalid payload received, not matching Payload struct. -- ");
Serial.print(radio.DATALEN);
Serial.print(" vs ");
Serial.println(sizeof(Payload));
} else {
payload = *(Payload*)radio.DATA; //assume radio.DATA actually contains our struct and not something else

sendReadingToSerial(radio.SENDERID, "float", "battery_level", "volts", payload.battery);
sendReadingToSerial(radio.SENDERID, "float", "signal_strength", "db", radio.RSSI);
sendReadingToSerial(radio.SENDERID, "float", "audio_level", "db", payload.volume);

if (radio.ACKRequested()) {
radio.sendACK();
Serial.print("# ACK sent.");
}
}

Serial.println();
Blink(3, 1);
}
}


// Helper function to blink the LED
void Blink(int delayms, int numberTimes) {
pinMode(LED, OUTPUT);
for (int x=0; x < numberTimes; x++) {
digitalWrite(LED, HIGH);
delay(delayms);
digitalWrite(LED, LOW);
}
}

// Reset the Radio
void resetRadio() {
Serial.print("# Resetting radio...");
pinMode(RF69_RESET, OUTPUT);
digitalWrite(RF69_RESET, HIGH);
delay(20);
digitalWrite(RF69_RESET, LOW);
delay(500);
Serial.println(" complete");
}

// Print Info
void printDebugInfo() {
char buff[50];
#if defined (__AVR_ATmega32U4__)
Serial.println("# AVR ATmega 32U4");
#else
Serial.println("# SAMD FEATHER M0");
#endif
#ifdef USING_RFM69_WING
Serial.println("# Using RFM69 Wing: YES");
#else
Serial.println("U# sing RFM69 Wing: NO");
#endif
Serial.print("# RF69_SPI_CS: "); Serial.println(RF69_SPI_CS);
Serial.print("# RF69_IRQ_PIN: "); Serial.println(RF69_IRQ_PIN);
Serial.print("# RF69_IRQ_NUM: "); Serial.println(RF69_IRQ_NUM);
#ifdef ENABLE_ATC
Serial.println("# RFM69 Auto Transmission Control: Enabled");
#else
Serial.println("# RFM69 Auto Transmission Control: Disabled");
#endif
if (promiscuousMode) {
Serial.println("# Promiscuous Mode: Enabled");
} else {
Serial.println("# Promiscuous Mode: Disabled");
}
#ifdef ENCRYPTKEY
Serial.println("# Encryption: Enabled");
#else
Serial.println("# Encryption: Disabled");
#endif
sprintf(buff, "# Listening at %d Mhz...", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
Serial.println(buff);
}

// sendReadingToSerial
void sendReadingToSerial(int sender_id, String dtype, String field_name, String unit, float value) {
// Build message
StaticJsonBuffer<200> jsonBuffer;
JsonObject& root = jsonBuffer.createObject();
root["device_id"] = "test_device_"+String(sender_id);
root["dtype"] = dtype;
root["name"] = field_name;
root["unit"] = unit;
root["value"] = value;
root["utc"] = "NOW";
char JSONmessage[300];
root.printTo(JSONmessage);
// Print to serial
root.printTo(Serial);
Serial.println();
delay(100);
}

// Identify yourself
void showMe() {
Blink(500, 2);
Blink(100, 10);
Blink(500, 2);
Blink(100, 10);
Blink(500, 2);
}



13 changes: 13 additions & 0 deletions device/rfm69/gateway/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# LittleSense - RFM69 Gateway
This example code demonstrates how data can be relayed to and from the LittleSense server via the Pi's Serial ports. Further information can be found in the main [LittleSense documentations](http://littlesense.readthedocs.io).

## Hardware
This example uses the [Adafruit Feather](https://www.adafruit.com/feather) modules. In particular the [Feather M0 RFM69HCW](https://www.adafruit.com/product/3177]) or the [Feather 32U4 RFM69HCW](https://www.adafruit.com/product/3077]). However the code can be adapted to work with any RFM69 Feather boards. We chose this boards because Adafruit has very good tutorials on how you can utilise these boards to develope sensors.

### Dependancies
Adafruit has really detailed [instructions](https://learn.adafruit.com/adafruit-feather-m0-radio-with-rfm69-packet-radio/overview) on how to get started with their Feather boards, so we are not going to repeat what is already well documented.

Once you are up and running you need the ArduinoJson library. Open the libraries manager in the Arduino IDE and search for "ArduinoJson". You should see a result titled: "ArduinoJson by Benolt Blanchon", click install. For more information and troubleshooting see the [Arduino JSON website](https://arduinojson.org/doc/installation/).

## Software
The file `gateway.ino` contains all the code you need. Open it up in the Arduino IDE, read the comments and change the settings as instructed. Make sure you select the correct port and board from the menu and upload. To test open the serial viewer or use the serial manager built into the LittleSense server.

0 comments on commit 04eb63f

Please sign in to comment.