Changeset - c21de31ee856
[Not reviewed]
default
0 6 0
ethanzonca@CL-ENS241-08.cedarville.edu - 12 years ago 2013-01-30 21:20:33
ethanzonca@CL-ENS241-08.cedarville.edu
Added labeling feature to logged data for sensor data types,
slave data request system now fully functional. Note: logger node
is no longer selected as previously planned.
6 files changed with 89 insertions and 16 deletions:
0 comments (0 inline, 0 general)
master/master/config.h
Show inline comments
 
@@ -7,96 +7,98 @@
 
 * Matthew Kanning
 
 * Kyle Ripperger
 
 * Matthew Kroening
 
 *
 
 */
 
 
#ifndef CONFIG_H_
 
#define CONFIG_H_
 
 
// --------------------------------------------------------------------------
 
// Module config (master.c)
 
// --------------------------------------------------------------------------
 
 
#define DEBUG_OUTPUT
 
 
#define F_CPU 11059200
 
#define MODULE_ID '1'
 
#define BOARDTEMP_ADDR 0x90
 
 
#define HEATER_THRESHOLD 70
 
 
// --------------------------------------------------------------------------
 
// Error Codes config (led.c, used throughout code)
 
// --------------------------------------------------------------------------
 
 
// SD Card
 
#define ERROR_SD_INIT 2
 
#define ERROR_SD_PARTITION 3
 
#define ERROR_SD_FILE 4
 
 
#define ERROR_XBEETIMEOUT 5
 
#define ERROR_NOXBEE 6
 
 
#define ERROR_CRAP 15
 
 
#define ERROR_ATFAIL 3
 
#define ERROR_EXITAT 8
 
 
// --------------------------------------------------------------------------
 
// Slave Sensors config (slavesensors.c)
 
// --------------------------------------------------------------------------
 
 
#define MAX_NUM_SLAVES 5  // Maximum number of nodes in the system
 
#define MAX_NUM_SENSORS 20 // Maximum number of unique types of sensors in the system
 
 
// Node identifier of log destination xbee
 
#define XBEE_LOGDEST_NAME "HAB-LOGGER"
 
 
#define DATAREQUEST_RATE 3000
 
 
// --------------------------------------------------------------------------
 
// Command Parser config (serparser.c)
 
// --------------------------------------------------------------------------
 
 
// Maximum payload size of command
 
#define MAX_PAYLOAD_LEN 16
 
 
// Circular serial buffer size. Must be at least MAX_CMD_LEN + 5
 
#define BUFFER_SIZE 32 
 
 
// Public broadcast address
 
#define BROADCAST_ADDR 0 
 
 
 
// --------------------------------------------------------------------------
 
// GPS config (xxx.c)
 
// --------------------------------------------------------------------------
 
#define NMEABUFFER_SIZE 150
 
 
// --------------------------------------------------------------------------
 
// USART config (serial.c)
 
// --------------------------------------------------------------------------
 
 
#define USART0_BAUDRATE 115200
 
#define USART1_BAUDRATE 115200
 
 
 
// --------------------------------------------------------------------------
 
// AX.25 config (ax25.c)
 
// --------------------------------------------------------------------------
 

	
 
// TX delay in milliseconds
 
#define TX_DELAY      500
 

	
 
// Maximum packet delay
 
#define MAX_PACKET_LEN 512  // bytes
 
 

	
 
// --------------------------------------------------------------------------
 
// APRS config (aprs.c)
 
// --------------------------------------------------------------------------
 

	
 
// Set your callsign and SSID here. Common values for the SSID are
 
// (from http://zlhams.wikidot.com/aprs-ssidguide):
 
//
 
// - Balloons:  11
 
// - Cars:       9
 
// - Home:       0
master/master/lib/led.c
Show inline comments
 
@@ -13,93 +13,100 @@
 
#include "../config.h"
 
#include <avr/io.h>
 
#include <util/delay.h>
 
#include <stdbool.h>
 
#include "led.h"
 
 
// Configure port direction and initial state of LEDs
 
void led_setup() 
 
{
 
	for(int i=0; i<NUM_LEDS; i++)  {
 
		*(ledList[i].direction) |= (1<<ledList[i].pin); // set pin to output
 
		*(ledList[i].port) &= ~(1<<ledList[i].pin); // set pin low
 
	}
 
}
 
 
// Turn the specified LED on
 
void led_on(uint8_t led) 
 
{
 
	*(ledList[led].port) |= (1<<ledList[led].pin);
 
}
 
 
	// Turn the specified LED off
 
void led_off(uint8_t led) 
 
{
 
	*(ledList[led].port) &= ~(1<<ledList[led].pin);
 
}
 
 
void led_toggle(uint8_t led)
 
{
 
	*(ledList[led].port) ^= (1<<ledList[led].pin);
 
}
 
 
// Flashes error LED a set amount of times, then leaves it on
 
void led_errorcode(uint8_t code) 
 
{
 
	led_off(LED_ERROR);
 
	_delay_ms(400);
 
	for(int i=0; i<code; i++) 
 
	{
 
		led_on(LED_ERROR);
 
		_delay_ms(150);
 
		led_off(LED_ERROR);
 
		_delay_ms(150);
 
	}
 
	_delay_ms(400);
 
	led_on(LED_ERROR);
 
}
 
 
void led_alert() {
 
	led_on(LED_ACT0);
 
	led_on(LED_ACT1);
 
	led_on(LED_ACT2);
 
	led_on(LED_ACT3);
 
	_delay_ms(10);
 
}
 

	
 
uint8_t ctr = 0;
 
void led_spin() {
 
	
 
	if(ctr == 0) {
 
		led_on(LED_ACT0);
 
		led_off(LED_ACT1);
 
		led_off(LED_ACT2);
 
		led_off(LED_ACT3);
 
	}
 
	else if (ctr == 1) {
 
		led_on(LED_ACT1);
 
		led_off(LED_ACT0);
 
		led_off(LED_ACT2);
 
		led_off(LED_ACT3);
 
	}
 
	else if (ctr == 2) {
 
		led_on(LED_ACT2);
 
		led_off(LED_ACT1);
 
		led_off(LED_ACT0);
 
		led_off(LED_ACT3);
 
	}
 
	else if (ctr == 3) {
 
		led_on(LED_ACT3);
 
		led_off(LED_ACT1);
 
		led_off(LED_ACT2);
 
		led_off(LED_ACT0);
 
	}
 
	ctr = (ctr + 1) % 4;
 
}
 

	
 

	
 
bool pulseUp = true;
 
void led_pulsate() {
 
	if(OCR0B >= 240 && pulseUp)
 
		pulseUp = false;
 
	else if(OCR0B <= 12 && !pulseUp);
 
		pulseUp = true;
 
		
 
	if(pulseUp)
 
		OCR0B+=5;
 
	else
 
		OCR0B-=5;
 
	
 
}
 
\ No newline at end of file
master/master/lib/led.h
Show inline comments
 
@@ -22,50 +22,51 @@ enum leds {
 
	LED_ACT2,
 
	LED_ACT3,
 
	
 
	LED_POWER,
 
	LED_STATUS,
 
	LED_ERROR,
 
	LED_SIDEBOARD,
 
	LED_ACTIVITY,
 
	LED_CYCLE,
 
	LED_HEAT,
 
	LED_BUZZ,
 
};
 
 
typedef struct {uint8_t* direction; uint8_t* port; uint8_t pin;} led_t;
 
 
// Match order of leds enum
 
static led_t ledList[] = {
 
	{&DDRA, &PORTA, PA1}, // ACT0
 
	{&DDRA, &PORTA, PA2}, // ACT1
 
	{&DDRA, &PORTA, PA3}, // ACT2
 
	{&DDRA, &PORTA, PA4}, // ACT3
 
 
//pcb:
 
	{&DDRB, &PORTB, PB4}, // POWER
 
	{&DDRB, &PORTB, PB3}, // STATUS
 
	{&DDRB, &PORTB, PB2}, // ERROR
 
 
//breadboard:
 
//	{&DDRA, &PORTA, PA2}, // POWER
 
//	{&DDRA, &PORTA, PA0}, // STATUS
 
//	{&DDRA, &PORTA, PA1}, // ERROR
 
 
	{&DDRD, &PORTD, PD6}, // SIDEBOARD
 
	{&DDRD, &PORTD, PD5}, // ACTIVITY
 
	{&DDRD, &PORTD, PD4}, // CYCLE
 
	
 
	{&DDRA, &PORTA, PA6}, // HEAT
 
	{&DDRA, &PORTA, PA7}, // BUZZER
 
};
 
 
#define NUM_LEDS 12
 
 
void led_setup();
 
void led_on(uint8_t led);
 
void led_off(uint8_t led);
 
void led_toggle(uint8_t led);
 
void led_errorcode(uint8_t code);
 
void led_spin();
 
void led_alert();
 
 
#endif /* LED_H_ */
master/master/lib/slavesensors.c
Show inline comments
 
/*
 
 * Master Firmware: Slave Sensor Data Aquisition
 
 *
 
 * Wireless Observational Modular Aerial Network
 
 * 
 
 * Ethan Zonca
 
 * Matthew Kanning
 
 * Kyle Ripperger
 
 * Matthew Kroening
 
 *
 
 */
 
 
#include "../config.h"
 
#include <avr/io.h>
 
#include <stdbool.h>
 
#include <stdlib.h>
 
#include <stdio.h>
 
#include <string.h>
 
#include <util/delay.h>
 
#include <avr/wdt.h>
 
#include <avr/pgmspace.h>
 
#include "serial.h"
 
#include "serparser.h"
 
#include "slavesensors.h"
 
#include "sensordata.h"
 
#include "led.h"
 
#include "looptime.h"
 

	
 
// Label lookup table
 
const char label_0[] PROGMEM = "BoardTemp";
 
const char label_1[] PROGMEM = "HeaterStatus";
 
const char label_2[] PROGMEM = "BatteryLevel";
 
const char label_3[] PROGMEM = "AirTemp";
 
const char label_4[] PROGMEM = "AmbientLight";
 
const char label_5[] PROGMEM = "Humidity";
 
const char label_6[] PROGMEM = "Pressure";
 
const char label_7[] PROGMEM = "Altitude";
 
const char label_8[] PROGMEM = "CPM-Radiation";
 

	
 
const char *const labelLookup[] PROGMEM =
 
{
 
	label_0,
 
	label_1,
 
	label_2,
 
	label_3,
 
	label_4,
 
	label_5,
 
	label_6,
 
	label_7,
 
	label_8,
 
};
 

	
 
char labelBuffer[25]; // Size to length of label
 
char* slavesensors_getLabel(uint8_t sensorID) {
 
	strncpy_P(labelBuffer,(char*)pgm_read_word(&(labelLookup[sensorID])),25);
 
	return labelBuffer;
 
}
 

	
 
uint8_t currentSlave = 0;
 
uint8_t currentSlaveSensor = 0;
 
 
bool requesting = false;
 
 
void slavesensors_setup() 
 
{
 
	
 
}
 

	
 
//#define DEBUG_NETWORKSCAN
 
//#define DEBUG_GETSLAVEDATA
 
#define DEBUG_GETSLAVEDATA
 
 
char* bufPtr = 0x00;
 

	
 
static char slaveAddressLow[MAX_NUM_SLAVES][9];
 
static char slaveAddressHigh[MAX_NUM_SLAVES][9];
 
static char slaveNames[MAX_NUM_SLAVES][20];
 

	
 
uint8_t loggerIndex = 255;
 
uint8_t nodeCount = 0;
 
bool dataReady = false;
 

	
 
char* slavesensors_slavename(uint8_t id) {
 
	return slaveNames[id];
 
}
 

	
 
void slavesensors_network_scan() {
 
	serial0_ioff();
 
	
 
	int atOK;
 
	
 
	#ifdef DEBUG_OUTPUT
 
	serial0_sendString("Beginning network scan...\r\n\r\n");
 
	#endif
 
	
 
	_delay_ms(500); // xbee warmup
 
	wdt_reset();
 
	
 
	led_on(LED_ACTIVITY);
 
	atOK = slavesensors_enterAT();
 
	
 
	// wait for OK
 
	if(atOK == 0)
 
	{
 
		led_on(LED_CYCLE);
 
		serial0_sendString("ATND");
 
		serial0_sendChar(0x0D);
 
		
 
		// wait for scan to complete
 
		uint16_t scanStart = time_millis(); 		
 
		while(!serial0_hasChar()) {
 
			if(time_millis() - scanStart > 7000) {
 
				led_errorcode(ERROR_XBEETIMEOUT);
 
				return;
 
			}
 
			wdt_reset();
 
		}
 
		// Scan data end when newline by itself ("")	
 
		int lineCount = 0;	
 
@@ -123,323 +154,346 @@ void slavesensors_network_scan() {
 
	// Display number of found nodes on spinning indicator
 
	switch(nodeCount) {
 
		case 0:
 
			break;
 
		case 3:
 
			led_on(LED_ACT2);
 
			_delay_ms(100);
 
		case 2:
 
			led_on(LED_ACT1);
 
			_delay_ms(100);	
 
		case 1:
 
			led_on(LED_ACT0);
 
			_delay_ms(100);
 
	}
 
	
 
	led_on(LED_SIDEBOARD);
 
	_delay_ms(200);
 
	led_off(LED_SIDEBOARD);
 

	
 
	#ifdef DEBUG_OUTPUT
 
	
 
	char debugBuf[64];
 
	serial0_sendString("Discovered: \r\n");
 
	for(int i=0; i<nodeCount; i++) {
 
		snprintf(debugBuf, 64, "  %s - %s%s (%u)\r\n", slaveNames[i],slaveAddressHigh,slaveAddressLow[i], i);
 
		serial0_sendString(debugBuf);
 
	}
 
	serial0_sendString("\r\n");
 
	if(atOK != 0) {
 
		serial0_sendString("AT mode failed \r\n");
 
	}
 
	
 
	#endif
 
	
 
	for(int i=0; i<nodeCount; i++) 
 
	{
 
		if(strcmp(slaveNames[i], XBEE_LOGDEST_NAME) == 0) 
 
		{
 
			loggerIndex = i;
 
		}
 
	}
 
	_delay_ms(100);
 
	
 
	slavesensors_selectlogger();
 
	
 
	serial0_ion();
 
}
 
 
// #define DEBUG_SELECTNODE
 
//#define DEBUG_CONTEXTSWITCH
 
//#define DEBUG_SELECTNODE
 
 
uint8_t selectedNode = 0;
 
uint8_t slavesensors_getselectednode() {
 
	return selectedNode;
 
}
 
 
void slavesensors_selectnode(uint8_t nodeIndex)
 
{
 
	if(selectedNode == nodeIndex) {
 
		return;
 
	}
 
	serial0_ioff();
 
	
 
	#ifdef DEBUG_CONTEXTSWITCH
 
	uint32_t startTime = time_millis();
 
	#endif
 
	
 
	#ifdef DEBUG_SELECTNODE
 
	serial0_sendString("Switch to node ");
 
	serial0_sendChar(nodeIndex + 0x30);
 
	serial0_sendString("\r\n");
 
	#endif
 
	
 
	_delay_ms(20);
 
	char tmpBuf[23];
 
	
 
	// If we can get into AT mode
 
	if(slavesensors_enterAT() == 0) {
 
		
 
		snprintf(tmpBuf, 23, "ATDH %s%c",slaveAddressHigh[nodeIndex], 0x0D);
 
		serial0_sendString(tmpBuf);
 
		
 
		if(xbeeIsOk() != 0) {
 
			led_errorcode(ERROR_NOXBEE);
 
			return;
 
		}
 
		
 
		snprintf(tmpBuf, 23, "ATDL %s%c",slaveAddressLow[nodeIndex], 0x0D);
 
		serial0_sendString(tmpBuf);
 
		
 
		if(xbeeIsOk() != 0) {
 
			led_errorcode(ERROR_NOXBEE);
 
			return;
 
		}
 
		
 
		slavesensors_exitAT();
 
		selectedNode = nodeIndex;
 
	}
 
	_delay_ms(2);
 
	
 
	#ifdef DEBUG_SELECTNODE
 
	serial0_sendString("Selected ");
 
	serial0_sendChar(nodeIndex + 0x30);
 
	serial0_sendString("\r\n");
 
	#endif
 
	
 
	#ifdef DEBUG_CONTEXTSWITCH
 
	uint32_t switchTime = time_millis() - startTime;
 
	char tmpB[32];
 
	snprintf(tmpB, 32, "CTXSW: %lu ms\r\n", switchTime);
 
	serial0_sendString(tmpB);
 
	#endif
 
	
 
	serial0_ion();
 
	return;
 
}
 
 
void slavesensors_selectlogger() 
 
{
 
	if(loggerIndex != 255) {
 
		slavesensors_selectnode(loggerIndex);
 
	}	
 
}
 
 
void slavesensors_exitAT() 
 
{
 
	// Exit AT
 
	serial0_sendString("ATCN");
 
	serial0_sendChar(0x0D);
 
	_delay_ms(2);
 
	//// Wait until we get "OK"
 
	//int atStart = time_millis();
 
	//while(!serial0_hasChar()) {
 
		//if(time_millis() - atStart > 500) {
 
			//led_errorcode(ERROR_EXITAT);
 
			//wdt_reset();
 
			//return 1;
 
		//}
 
	//};
 
	
 
	xbeeIsOk();
 
}
 
 
// Enter AT mode. Leaves "OK" on the buffer.
 
int slavesensors_enterAT() 
 
{
 
	// Delay guard time
 
	_delay_ms(2);
 
 
 
	serial0_ioff(); // interrupts MUST be off
 
	
 
	// Enter AT mode
 
	serial0_sendChar('+'); // Enter AT mode
 
	serial0_sendChar('+');
 
	serial0_sendChar('+');
 
	_delay_ms(2);
 
	// Wait 1ms until we get "OK"
 
	//int atStart = time_millis();
 
	//while(!serial0_hasChar()) {
 
		//if(time_millis() - atStart > 500) {
 
			//led_errorcode(ERROR_ATFAIL);
 
			//wdt_reset();
 
			//return 1;
 
		//}
 
	//};	
 
	
 
	return xbeeIsOk();
 
 
}
 
 
int xbeeIsOk() 
 
{
 
	char* tmppntr = serial0_readLine();
 
	if(strcmp(tmppntr, "OK") == 0)
 
	{
 
		return 0;
 
	}
 
	else
 
	{
 
		led_errorcode(ERROR_NOXBEE);
 
		return 1;
 
	}
 
}
 
 
bool slavesensors_dataReady() {
 
	return dataReady;
 
}
 
 
bool slavesensors_isrequesting() 
 
{
 
	return requesting;	
 
}
 
 
void slavesensors_startprocess() 
 
{
 
	requesting = true;
 
	slavesensors_request();		
 
}
 
 
// TODO: inline. static.
 
void slavesensors_request() 
 
{
 
	if(currentSlave == loggerIndex) {
 
		currentSlave++;
 
		if(currentSlave >= (nodeCount)) {
 
			slavesensors_selectlogger();
 
			return;
 
		}
 
	}
 
	slavesensors_selectnode(currentSlave);
 
	serial_sendCommand("@"); // Request data!
 
	slavesensors_selectlogger();
 
}
 
 
 
uint8_t numReadingsToExpect = 0; // number of values that the slave is about to send (testing)
 
 
 
// TODO: needs to skip logger!
 
void slavesensors_process(uint8_t parseResult) 
 
{
 
	if(!requesting) {
 
		// we got a command when we didn't request anything. probably skip it.
 
		return;
 
	}
 
	
 
	// TODO: timeout. If we're at NODATA for a long time and we are requesting, that's an issue.
 
	// TODO: If we time out, WE NEED TO RESET THE PARSER. It could be in a bad state.
 
	else if(parseResult == PARSERESULT_NODATA) {
 
		// Wait for data
 
	}
 
	
 
	// Finished reception of a message (one sensor data value). If not finished, send out command to get the next one
 
	else if(parseResult == PARSERESULT_PARSEOK)
 
	{
 
		
 
		#ifdef DEBUG_GETSLAVEDATA
 
		char debug[50];
 
		snprintf(debug, 50, "Slave %u sensor %u of total nodes %u\r\n", currentSlave, currentSlaveSensor,nodeCount);
 
		serial0_sendString(debug);
 
		#endif
 
		
 
		// We got some data, let's handle it
 
		// ASCII payload
 
		uint8_t len = getPayloadLength();
 
		uint8_t* load = getPayload();
 
		uint8_t type = getPayloadType();
 
		uint16_t parsedVal = atoi(load);
 

	
 
		// Special case for slave telling us how many things we're about to get		
 
		if(type + 0x30 == '@') {
 
			
 
			#ifdef DEBUG_GETSLAVEDATA
 
			serial0_sendString("Got an awesome count!\r\n");
 
			serial0_sendChar(parsedVal + 0x30);
 
			serial0_sendString("\r\n");
 
			#endif
 
			
 
			numReadingsToExpect = parsedVal;
 
			currentSlaveSensor = 0;
 
			requesting = true;
 
		}
 
		else {
 
		
 
			// Store data in structure
 
			sensordata_set(currentSlave,type,parsedVal);
 
			
 
			#ifdef DEBUG_GETSLAVEDATA
 
			serial0_sendString("Stored some sexy data!\r\n");
 
			#endif 
 
			
 
			// If we finished all sensors for all slaves
 
			
 
			if(currentSlave >= (nodeCount-1) && currentSlaveSensor >= (numReadingsToExpect-1))
 
			{
 
				#ifdef DEBUG_GETSLAVEDATA
 
				serial0_sendString("We got all data for all slaves!\r\n");
 
				#endif
 
				
 
				dataReady = true;
 
				currentSlave = 0;
 
				currentSlaveSensor = 0;
 
				requesting = false;
 
				led_alert();
 
			}
 
			// If we finished up one slave, go to the next
 
			else if(currentSlaveSensor >= (numReadingsToExpect-1)) 
 
			{
 
				#ifdef DEBUG_GETSLAVEDATA
 
				serial0_sendString("Finished up one slave, go to another.\r\n");
 
				#endif
 
				
 
				currentSlave++;
 
				currentSlaveSensor = 0;
 
				requesting = true;
 
				
 
				if(currentSlave == loggerIndex) {
 
					if(currentSlave >= (nodeCount-1)) {
 
						// We hit the last one, we're done.
 
						dataReady = true;
 
						currentSlave = 0;
 
						currentSlaveSensor = 0;
 
						requesting = false;
 
						led_alert();
 
						return;
 
					}
 
					else {
 
						currentSlave++; // increment to the next slave after the logger
 
					}
 
				}
 
				
 
				slavesensors_request();
 
			}
 
			// If we haven't finished a slave (or all of them), just get the next sensor of the current slave
 
			else
 
			{
 
				#ifdef DEBUG_GETSLAVEDATA
 
				serial0_sendString("Give me another sensor value...");
 
				#endif
 
				
 
				// request data for the current sensor of the current slave
 
				currentSlaveSensor++;
 
				requesting = true;
 
				//slavesensors_request();	 slaves now send all values at once, we don't need to keep requesting
 
			}
 
		}
 
	}
 
	
 
	// If fail, try retransmit. Or we could skip and hit it next time.
 
	// TODO: Maximum number of retransmissions
 
	else if(parseResult == PARSERESULT_FAIL) {
 
		if(requesting) {
 
			slavesensors_request();	// re-request
 
		}			
 
	}
 
	
 
	
 
	else if(parseResult == PARSERESULT_STILLPARSING)
 
	{
 
		return; // do nothing
 
	}
 
	else {
 
		// something is terribly wrong!
 
		return;
 
	}
 
}		
 
\ No newline at end of file
master/master/lib/slavesensors.h
Show inline comments
 
/*
 
 * Master Firmware: Slave Sensor Data Aquisition
 
 *
 
 * Wireless Observational Modular Aerial Network
 
 * 
 
 * Ethan Zonca
 
 * Matthew Kanning
 
 * Kyle Ripperger
 
 * Matthew Kroening
 
 *
 
 */
 
 
 
#ifndef SLAVESENSORS_H_
 
#define SLAVESENSORS_H_
 
 
#include <stdbool.h>
 
#include <inttypes.h>
 
 
// Serial Commands
 
enum sensorTypes // CMD ID#
 
{
 
	NONE = 0,
 
	BOARDTEMP,
 
	PRESSURE,
 
	GEIGER,
 
	TEMPERATURE,
 
	HUMIDITY,
 
	AMBIENTLIGHT,
 
	CAMERA,
 
};
 
 
char* slavesensors_getLabel(uint8_t sensorID);
 
char* slavesensors_slavename(uint8_t id);
 
bool slavesensors_dataReady();
 
bool slavesensors_isrequesting();
 
void slavesensors_setup();
 
void slavesensors_network_scan();
 
uint8_t slavesensors_getselectednode();
 
void slavesensors_selectnode(uint8_t nodeIndex);
 
void slavesensors_startprocess();
 
void slavesensors_request();
 
void slavesensors_process(uint8_t parseResult);
 
int xbeeIsOk();
 
void slavesensors_selectlogger();
 
void slavesensors_exitAT();
 
int slavesensors_enterAT();
 
 
#endif /* SLAVESENSORS_H_ */
 
\ No newline at end of file
master/master/master.c
Show inline comments
 
@@ -32,170 +32,176 @@
 

	
 
#include "lib/i2c.h"
 
#include "lib/boardtemp.h"
 
#include "lib/heater.h"
 
#include "lib/looptime.h"
 
#include "lib/slavesensors.h"
 
#include "lib/serparser.h"
 
#include "lib/sensordata.h"
 

	
 
int main(void)
 
{
 
	// Initialize libraries
 
	time_setup();
 
	watchdog_setup(); // enables interrupts
 
	led_setup();
 
	
 
	led_on(LED_POWER);
 
	led_on(LED_BUZZ);
 
	_delay_ms(1);
 
	led_off(LED_BUZZ);
 
	
 
	gps_setup();
 
	serial0_setup();
 
	serial1_setup();
 
	i2c_init();
 
	sensordata_setup(); // must happen before sensors/logger/afsk
 
	slavesensors_setup();
 
	logger_setup();
 
	afsk_setup();
 
	//\f
 
	
 
	#ifdef DEBUG_OUTPUT
 
	serial0_sendString("\r\n---------------------------------\r\n");
 
	serial0_sendString("HAB Controller 1.0 - Initialized!\r\n");
 
	serial0_sendString("---------------------------------\r\n");
 
	#endif
 
	
 
	serial0_sendString("\r\nHello.\r\n\r\n");
 
	
 
	slavesensors_network_scan(); // This can take a little while
 
	
 
	// Buffer for string operations
 
	char logbuf[128];
 
	
 
	// Software timers	
 
	uint32_t lastAprsBroadcast = 0;
 
	uint32_t lastLog = 0;
 
	uint32_t lastLedCycle = 0;
 
	uint32_t lastDataReq = 0;
 
	
 
	bool dataWasReady = false;
 
	
 
	// Result of last parser run
 
	int parseResult = PARSERESULT_NODATA;
 
	
 
	serial1_ioff();
 
	
 
	while(1)
 
    {
 
		
 
		// Periodic: LED execution indicator
 
		if(time_millis() - lastLedCycle > LEDCYCLE_RATE) {
 
			led_spin();
 
			
 
			if(!afsk_busy())
 
				serial1_ion();
 
			lastLedCycle = time_millis();	
 
		}
 
		
 
		// Periodic: Logging
 
		if(time_millis() - lastLog > LOGGER_RATE) 
 
		{
 
			led_on(LED_CYCLE);
 
			
 
			heater_regulateTemp();
 
			
 
			// Print out GPS debug
 
			//snprintf(debugBuf, 128, "GPS> time: %s lat: %s lon: %s speed: %s hdop: %s course: %s\r\n",
 
			//get_timestamp(),get_latitude(),get_longitude(),get_speedKnots(),get_hdop(), get_course());
 
			//serial0_sendString(debugBuf);
 
			
 
			// Turn on sideboard LED if we have a fix
 
			if(strcmp("99.99", get_hdop()) == 0) {
 
				led_off(LED_SIDEBOARD);
 
			}
 
			else {
 
				led_on(LED_SIDEBOARD);
 
			}
 
			
 
			sensors_readBoardTemp(); // i2c read, 400k
 
		
 
			// If we've gotten data from all slaves once, we're ready to make a CSV header and start logging
 
			if(slavesensors_dataReady()) {
 
				if(!dataWasReady) {
 
					char csvHeader[128];
 
					csvHeader[0] = 0x00;
 
					
 
					// Add master data headers
 
					snprintf(csvHeader, 128, "Time,BoardTemp,Lat,Lon,HDOP,Speed,GPS SV,");
 
					
 
					for(uint8_t i=0; i<MAX_NUM_SLAVES; i++) {
 
						for(uint8_t j=0; j<MAX_NUM_SENSORS; j++) {
 
							int16_t tmp = sensordata_get(i, j);
 
							if(tmp != -32768) {
 
								// FIXME: will the 128 here really provide safety? might want to subtract the strlen
 
								snprintf(csvHeader + strlen(csvHeader), 128,"%s-Sensor%u,", slavesensors_slavename(i), j);	
 
								snprintf(csvHeader + strlen(csvHeader), 128,"%s-%s,", slavesensors_slavename(i), slavesensors_getLabel(j));	
 
							}
 
						}
 
					}
 
					snprintf(csvHeader + strlen(csvHeader), 128,"\r\n");	
 
					serial0_sendString(csvHeader);
 
					logger_log(csvHeader);
 
					dataWasReady = true;
 
				}
 
		
 
				logbuf[0] = 0x00;
 
				snprintf(logbuf, 128, "%lu,%d,%u,%s,%s,%s,%s,%s", time_millis(), sensors_getBoardTemp(),get_timestamp(),get_latitude(),get_longitude(),get_speedKnots(),get_hdop(), get_course());
 
				for(int i=0; i<MAX_NUM_SLAVES; i++) {
 
					for(int j=0; j<MAX_NUM_SENSORS; j++) {
 
						int16_t tmp = sensordata_get(i, j);
 
						if(tmp != -32768) {
 
							snprintf(logbuf + strlen(logbuf),128," %d,", tmp);
 
						}
 
					
 
					}
 
				}
 
				snprintf(logbuf + strlen(logbuf),128,"\r\n");
 
				serial0_sendString(logbuf);			
 
				logger_log(logbuf);
 
			
 
			}			
 
			
 
			// Print out logger debug
 
			#ifdef DEBUG_OUTPUT
 
			//serial0_sendString("LOG> ");
 
			//serial0_sendString(logbuf);
 
			#endif
 
			
 
			led_off(LED_CYCLE);
 
			lastLog = time_millis();
 
		}		
 
		
 
		
 
		// Periodic: Data Request
 
		if(time_millis() - lastDataReq > DATAREQUEST_RATE)  {
 
			// Start getting values for next transmission
 
			if(slavesensors_isrequesting())
 
			{
 
				// TODO: something is terribly wrong
 
			}
 
			else
 
			{
 
				slavesensors_startprocess();
 
			}
 
			
 
			lastDataReq = time_millis();
 
		}
 
		
 
		
 
		// Periodic: APRS transmission
 
		if(time_millis() - lastAprsBroadcast > APRS_TRANSMIT_PERIOD) 
 
		{
 
			while(afsk_busy());
 
			serial1_ioff();
 
			aprs_send(); // non-blocking
 
			
 
			//serial0_sendString("Initiating APRS transmission...\r\n");
 
			
 
			// Start getting values for next transmission
 
			if(slavesensors_isrequesting())
 
			{
 
				// TODO: something is terribly wrong
 
			}
 
			else 
 
			{				
 
				slavesensors_startprocess();
 
			}
 
			
 
			lastAprsBroadcast = time_millis();
 
		}			
 
		
 

	
 
		parseResult = serparser_parse();
 
		slavesensors_process(parseResult);
 
		parse_gps_transmission();
 
		wdt_reset();
 
    }
 
}
 
\ No newline at end of file
0 comments (0 inline, 0 general)