Skip to content

Commit

Permalink
Update camera and telemetry board sketches to those in use on PAN006.
Browse files Browse the repository at this point in the history
These have the benefit that they produce their reports faster because
they first gather the data needed before they start writing. This
reduces the risk that POCS will timeout while reading a single report.
  • Loading branch information
jamessynge committed Jan 3, 2018
1 parent ce519ae commit 1352e38
Show file tree
Hide file tree
Showing 2 changed files with 780 additions and 337 deletions.
349 changes: 224 additions & 125 deletions resources/arduino_files/camera_board/camera_board.ino
Original file line number Diff line number Diff line change
Expand Up @@ -5,162 +5,261 @@
#include "Adafruit_Sensor.h"
#include "DHT.h"

#define DHT_TYPE DHT22 // DHT 22 (AM2302)

/* DECLARE PINS */
const int DHT_PIN = 9; // DHT Temp & Humidity Pin
const int CAM_01_RELAY = 5;
const int CAM_02_RELAY = 6;
const int CAM_0_RELAY = 5;
const int CAM_1_RELAY = 6;
const int RESET_PIN = 12;

// Utitlity Methods

void toggle_led() {
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}

void turn_pin_on(int pin_num) {
digitalWrite(pin_num, HIGH);
}

void turn_pin_off(int pin_num) {
digitalWrite(pin_num, LOW);
}

// IO Handlers.

/* CONSTANTS */
Adafruit_MMA8451 accelerometer = Adafruit_MMA8451();
class AccelerometerHandler {
public:
void init() {
ready_ = false;
has_reading_ = false;
ready();
}
void collect() {
if (ready()) {
accelerometer_.getEvent(&event_);
orientation_ = accelerometer_.getOrientation(); // Orientation
has_reading_ = true;
}
}
bool report() {
if (has_reading_) {
Serial.print(", \"accelerometer\":{\"x\":");
Serial.print(event_.acceleration.x);
Serial.print(", \"y\":");
Serial.print(event_.acceleration.y);
Serial.print(", \"z\":");
Serial.print(event_.acceleration.z);
Serial.print(", \"o\": "); Serial.print(orientation_);
Serial.print("}");
return true;
}
return false;
}
bool ready() {
if (!ready_) {
ready_ = accelerometer_.begin();
if (!ready_) {
Serial.println("Accelerometer not ready, or not present.");
} else {
// Check Accelerometer range
// accelerometer.setRange(MMA8451_RANGE_2_G);
// Serial.print("Accelerometer Range = "); Serial.print(2 << accelerometer.getRange());
// Serial.println("G");
}
}
return ready_;
}

// Setup DHT22
DHT dht(DHT_PIN, DHT_TYPE);
private:
Adafruit_MMA8451 accelerometer_;
sensors_event_t event_;
uint8_t orientation_;
bool ready_;
bool has_reading_;
} acc_handler;

int led_value = LOW;
class DHTHandler {
public:
DHTHandler() : dht_(DHT_PIN, DHT22) {} // AM2302

void init() {
dht_.begin();
}

void collect() {
// Force readHumidity to actually talk to the device;
// otherwise will read at most every 2 seconds, which
// is sometimes just a too far apart.
// Note that the underlying read() routine has some big
// delays (250ms and 40ms, plus some microsecond scale delays).
humidity_ = dht_.readHumidity(/*force=*/true);
// readTemperature will use the data collected by
// readHumidity, which is just fine.
temperature_ = dht_.readTemperature();
}

void report() {
Serial.print(", \"humidity\":");
Serial.print(humidity_);
Serial.print(", \"temp_00\":");
Serial.print(temperature_);
}

private:
DHT dht_;
float humidity_ = 0;
float temperature_ = 0; // Celcius
} dht_handler;

unsigned long end_setup_millis;
unsigned long next_report_millis;
int report_num = 0;

class LedHandler {
public:
void init() {
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, false);

// Provide a visible signal that setup has been entered.
if (Serial) {
// 2 seconds of fast blinks.
for (int i = 0; i < 40; ++i) {
delay(50);
toggle_led();
}
Serial.println("LED blink complete");
} else {
// 2 seconds of slow blinks.
for (int i = 0; i < 10; ++i) {
delay(200);
toggle_led();
}
}
}

void update() {
unsigned long now = millis();
if (next_change_ms_ <= now) {
toggle_led();
next_change_ms_ += (Serial ? 1000 : 100);
if (next_change_ms_ <= now) {
next_change_ms_ = now;
}
}
}

private:
unsigned long next_change_ms_ = 0;
} led_handler;

void setup(void) {
Serial.begin(9600);
Serial.flush();

// Turn off LED inside camera box
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
led_handler.init();

// Setup Camera relays
pinMode(CAM_01_RELAY, OUTPUT);
pinMode(CAM_02_RELAY, OUTPUT);

pinMode(RESET_PIN, OUTPUT);
pinMode(CAM_0_RELAY, OUTPUT);
pinMode(CAM_1_RELAY, OUTPUT);

// Turn on Camera relays
turn_pin_on(CAM_01_RELAY);
turn_pin_on(CAM_02_RELAY);

if (! accelerometer.begin()) {
while (1);
}
turn_pin_on(CAM_0_RELAY);
turn_pin_on(CAM_1_RELAY);

dht.begin();
acc_handler.init();
dht_handler.init();

// Check Accelerometer range
// accelerometer.setRange(MMA8451_RANGE_2_G);
// Serial.print("Accelerometer Range = "); Serial.print(2 << accelerometer.getRange());
// Serial.println("G");
Serial.println("EXIT setup()");
next_report_millis = end_setup_millis = millis();
}

void loop() {

led_handler.update();
if (Serial) {
main_loop();
}
}

static int inputs = 0;

void main_loop() {
unsigned long now = millis();
if (next_report_millis <= now) {
// Schedule the next report for `interval' milliseconds from the last report,
// unless we've fallen behind.
constexpr int interval = 1000;
next_report_millis += interval;
if (next_report_millis <= now) {
next_report_millis = now + interval;
}

// Collect the data. Since some of these operations take a while, keep updating the
// LED as appropriate. Could probably be done with an interrupt handler instead.
report_num++;
acc_handler.collect();
led_handler.update();
dht_handler.collect();
led_handler.update();
bool cam0 = digitalRead(CAM_0_RELAY);
bool cam1 = digitalRead(CAM_1_RELAY);

// Format/output the results.
Serial.print("{\"name\":\"camera_board\", \"count\":");
led_handler.update();
Serial.print(millis() - end_setup_millis);
led_handler.update();
Serial.print(", \"num\":");
led_handler.update();
Serial.print(report_num);
led_handler.update();
Serial.print(", \"inputs\":");
led_handler.update();
Serial.print(inputs);
led_handler.update();
Serial.print(", \"camera_00\":");
led_handler.update();
Serial.print(cam0);
led_handler.update();
Serial.print(", \"camera_01\":");
led_handler.update();
Serial.print(cam1);
led_handler.update();
acc_handler.report();
led_handler.update();
dht_handler.report();
led_handler.update();
Serial.println("}");
led_handler.update();
Serial.flush();
led_handler.update();
}

// Read any serial input
// - Input will be two comma separated integers, the
// - Input will be two integers (with anything in between them), the
// first specifying the pin and the second the status
// to change to (1/0). Cameras and debug led are
// supported.
// Example serial input:
// 4,1 # Turn fan on
// 5,1 # Turn camera 0 on
// 6,0 # Turn camera 1 off
// 13,0 # Turn led off
while (Serial.available() > 0) {
inputs++;
int pin_num = Serial.parseInt();
int pin_status = Serial.parseInt();

switch (pin_num) {
case CAM_01_RELAY:
case CAM_02_RELAY:
if (pin_status == 1) {
turn_pin_on(pin_num);
} else if (pin_status == 0) {
turn_pin_off(pin_num);
} else if (pin_status == 9) {
toggle_pin(pin_num);
}
break;
case RESET_PIN:
if (pin_status == 1) {
turn_pin_off(RESET_PIN);
}
break;
case LED_BUILTIN:
digitalWrite(pin_num, pin_status);
break;
case CAM_0_RELAY:
case CAM_1_RELAY:
if (pin_status == 1) {
turn_pin_on(pin_num);
} else if (pin_status == 0) {
turn_pin_off(pin_num);
}
break;
case LED_BUILTIN:
digitalWrite(pin_num, pin_status);
break;
}
}

// Begin reading values and outputting as JSON string
Serial.print("{");

read_status();

read_accelerometer();

read_dht_temp();

Serial.print("\"name\":\"camera_board\""); Serial.print(",");

Serial.print("\"count\":"); Serial.print(millis());

Serial.println("}");

Serial.flush();
delay(1000);
}

void read_status() {

Serial.print("\"power\":{");
Serial.print("\"camera_00\":"); Serial.print(is_pin_on(CAM_01_RELAY)); Serial.print(',');
Serial.print("\"camera_01\":"); Serial.print(is_pin_on(CAM_02_RELAY)); Serial.print(',');
Serial.print("},");
}

/* ACCELEROMETER */
void read_accelerometer() {
/* Get a new sensor event */
sensors_event_t event;
accelerometer.getEvent(&event);
uint8_t o = accelerometer.getOrientation(); // Orientation

Serial.print("\"accelerometer\":{");
Serial.print("\"x\":"); Serial.print(event.acceleration.x); Serial.print(',');
Serial.print("\"y\":"); Serial.print(event.acceleration.y); Serial.print(',');
Serial.print("\"z\":"); Serial.print(event.acceleration.z); Serial.print(',');
Serial.print("\"o\": "); Serial.print(o);
Serial.print("},");
}

//// Reading temperature or humidity takes about 250 milliseconds!
//// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
void read_dht_temp() {
float h = dht.readHumidity();
float c = dht.readTemperature(); // Celsius

Serial.print("\"humidity\":"); Serial.print(h); Serial.print(',');
Serial.print("\"temp_00\":"); Serial.print(c); Serial.print(",");
}

/************************************
* Utitlity Methods
*************************************/

void toggle_led() {
led_value = ! led_value;
digitalWrite(LED_BUILTIN, led_value);
}

void toggle_pin(int pin_num) {
digitalWrite(pin_num, !digitalRead(pin_num));
}

void turn_pin_on(int camera_pin) {
digitalWrite(camera_pin, HIGH);
}

void turn_pin_off(int camera_pin) {
digitalWrite(camera_pin, LOW);
}

int is_pin_on(int camera_pin) {
return digitalRead(camera_pin);
}
Loading

0 comments on commit 1352e38

Please sign in to comment.