Changeset - e3153d5a767c
[Not reviewed]
default
0 6 0
ethanzonca@CL-ENS241-08.cedarville.edu - 12 years ago 2013-01-21 20:59:15
ethanzonca@CL-ENS241-08.cedarville.edu
Implemented new serial protocol and slave sensor data storage technique, appears to be functional.
6 files changed with 74 insertions and 87 deletions:
0 comments (0 inline, 0 general)
master/master/config.h
Show inline comments
 
@@ -34,38 +34,26 @@
 
#define ERROR_SD_PARTITION 3
 
#define ERROR_SD_FILE 4
 
 
#define ERROR_XBEETIMEOUT 5
 
#define ERROR_NOXBEE 6
 
 
#define ERROR_CRAP 15
 
 
// --------------------------------------------------------------------------
 
// Slave Sensors config (slavesensors.c)
 
// --------------------------------------------------------------------------
 
 
// NOT USED. Could integrate into slavesensors.c setup function for configurability eventually.
 
// Currently manual configuration of sensors is done in slavesensors.c
 
#define SLAVE0_SENSORS BOARDTEMP
 
#define SLAVE1_SENSORS BOARDTEMP | HUMIDITY | TEMPERATURE | PRESSURE | AMBIENTLIGHT
 
#define SLAVE2_SENSORS BOARDTEMP | GEIGER
 
#define SLAVE3_SENSORS BOARDTEMP | CAMERA
 
#define SLAVE4_SENSORS NONE
 
#define SLAVE5_SENSORS NONE
 
#define SLAVE6_SENSORS NONE
 
#define SLAVE7_SENSORS NONE
 
 
// MAX_SLAVES should be one more than the number of slaves we actually have (loop ends when next slave first sensor is NONE)
 
#define MAX_SLAVES 8
 
#define MAX_SLAVE_SENSORS 8
 
#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"
 
 
// --------------------------------------------------------------------------
 
// 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
master/master/lib/gps.c
Show inline comments
 
@@ -111,33 +111,28 @@ enum decodeState {
 
	RMC_TIME,
 
	RMC_VALIDITY,
 
	RMC_LATITUDE,
 
	RMC_LONGITUDE,
 
	RMC_KNOTS,
 
	RMC_COURSE,
 
	RMC_DATE,
 
	RMC_MAG_VARIATION,
 
	
 
}decodeState;
 

	
 

	
 
char debugBuff[128];
 

	
 
ISR(USART1_RX_vect)
 
{
 
	nmeaBuffer[nmeaBufferDataPosition % NMEABUFFER_SIZE] = UDR1;
 
	nmeaBufferDataPosition = (nmeaBufferDataPosition + 1) % NMEABUFFER_SIZE;
 
	//serial0_sendChar(UDR1);
 
	//snprintf(debugBuff, 32, "GPS: bdp: %d, bpp: %d decodestate: %u \r\n", nmeaBufferDataPosition, nmeaBufferParsePosition, decodeState);
 
	//serial0_sendString((debugBuff));
 
}
 

	
 

	
 
// Could inline if program space available
 
static void setParserState(uint8_t state)
 
{
 
	decodeState = state;
 
 
	
 
	// If resetting, clear vars
 
	if(state == INITIALIZE)
 
	{
 
@@ -154,27 +149,24 @@ static void setParserState(uint8_t state
 
void parse_gps_transmission(void){
 
	
 
	// Pull byte off of the buffer
 
	char byte;
 
	
 
	
 
	
 
	while(nmeaBufferDataPosition != nmeaBufferParsePosition) {
 
	led_on(LED_ACTIVITY);
 
		
 
		byte = nmeaBuffer[nmeaBufferParsePosition];
 
		
 
		//snprintf(debugBuff, 64, "GPSParse: byte [%c] decodestate: %u bp: %u pp: %u\r\n",  byte, decodeState, nmeaBufferDataPosition, nmeaBufferParsePosition);
 
		//serial0_sendString((debugBuff));
 
		
 
		if(decodeState == INITIALIZE) //start of transmission sentence
 
		{
 
			if(byte == '$') {
 
				#ifdef DEBUG_NMEA
 
				serial0_sendString("found $\r\n");
 
				#endif
 
				
 
				setParserState(GET_TYPE);
 
				numBytes = 0; //prep for next phases
 
				skipBytes = 0;
 
				calculatedChecksum = 0;
 
			}		
 
@@ -633,27 +625,26 @@ void parse_gps_transmission(void){
 
				//TODO: must determine what to do with correct and incorrect messages
 
				receivedChecksum = checksum[0] + (checksum[1]*16);	//convert bytes to int
 
				if(calculatedChecksum==receivedChecksum)
 
				{
 
				
 
				}
 
				else
 
				{
 
				
 
				}
 
				#ifdef DEBUG_NMEA
 
				serial0_sendString("OMG GOT TO CHECKSUM!\r\n");
 
				#endif
 
				#endif
 
				
 
				serial0_sendString((debugBuff));
 
				setParserState(INITIALIZE);
 
				numBytes = 0; //prep for next phase of parse
 
			}
 
			else //store data
 
			{
 
				setParserState(GPS_CHECKSUM);
 
				checksum[numBytes] = byte; //adjust number of bytes to fit array
 
				numBytes++;
 
			}
 
		}
 
		else {
 
			setParserState(INITIALIZE);
master/master/lib/sensordata.c
Show inline comments
 
@@ -4,42 +4,40 @@
 
 * Wireless Observational Modular Aerial Network
 
 * 
 
 * Ethan Zonca
 
 * Matthew Kanning
 
 * Kyle Ripperger
 
 * Matthew Kroening
 
 *
 
 */
 

	
 
#include "../config.h"
 
#include "sensordata.h"
 

	
 
int16_t boardTemps[MAX_SLAVES];
 
uint16_t variousSensors[MAX_SLAVES * (MAX_SLAVE_SENSORS - 1)];
 
int16_t slaves[MAX_NUM_SLAVES][MAX_NUM_SENSORS];
 

	
 
void sensordata_setup() 
 
{
 
	for(int i=0; i<MAX_SLAVES; i++)
 
	{
 
		boardTemps[i] = 0;
 
	for(int i=0; i<MAX_NUM_SLAVES; i++) {
 
		for(int j=0; j<MAX_NUM_SLAVES; j++) {
 
			slaves[i][j] = -32768; // minimum value of 16 bit integer
 
		}
 
	}
 
}
 
 
void sensordata_set(uint8_t type, uint16_t value) 
 
void sensordata_set(uint8_t nodeID, uint8_t type, uint16_t value)
 
{
 
	variousSensors[type] = value;
 
}
 
 
uint16_t sensordata_get(uint8_t type) 
 
{
 
	return variousSensors[type];
 
	if(nodeID < MAX_NUM_SLAVES) {
 
		slaves[nodeID][type] = value;
 
	}	
 
}
 
 
void sensordata_setBoardTemp(uint8_t slaveID, int16_t value) 
 
uint16_t sensordata_get(uint8_t nodeID, uint8_t type) 
 
{
 
	boardTemps[slaveID] = value;
 
	// Avoid reading out of bad places!
 
	if(nodeID < MAX_NUM_SLAVES) {
 
		return slaves[nodeID][type];
 
	}
 
	else {
 
		return 0;
 
	}
 
}
 
 
int16_t sensordata_getBoardTemp(uint8_t slaveID)
 
{
 
	return boardTemps[slaveID];
 
}
 
\ No newline at end of file
master/master/lib/sensordata.h
Show inline comments
 
@@ -8,18 +8,18 @@
 
 * Kyle Ripperger
 
 * Matthew Kroening
 
 *
 
 */
 
 
 
#ifndef SENSORDATA_H_
 
#define SENSORDATA_H_
 
 
#include "slavesensors.h"
 
 
void sensordata_setup();
 
void sensordata_set(uint8_t type, uint16_t value);
 
uint16_t sensordata_get(uint8_t type);
 
void sensordata_set(uint8_t nodeID, uint8_t type, uint16_t value);
 
uint16_t sensordata_get(uint8_t nodeID, uint8_t type);
 
void sensordata_setBoardTemp(uint8_t slaveID, int16_t value);
 
int16_t sensordata_getBoardTemp(uint8_t slaveID);
 
 
#endif /* SENSORDATA_H_ */
 
\ No newline at end of file
master/master/lib/serparser.c
Show inline comments
 
@@ -81,25 +81,25 @@ char debugBuff[16];
 
 
ISR(USART0_RX_vect)
 
{
 
	buffer[bufferDataPosition % BUFFER_SIZE] = UDR0;
 
	bufferDataPosition = (bufferDataPosition + 1) % BUFFER_SIZE;
 
	//sprintf(debugBuff, "bdp: %d, bpp: %d \r\n", bufferDataPosition, bufferParsePosition);
 
	//serial0_sendString((debugBuff)); 
 
}
 
 
 
 
 
#define DEBUG
 
//#define DEBUG
 
 
// Parse data from circular buffer
 
int serparser_parse(void)
 
{
 
	
 
	char byte;
 
 
	// Process first command (if any) on the circular buffer
 
	while(bufferDataPosition != bufferParsePosition)
 
	{
 
		byte = buffer[bufferParsePosition];
 
		
 
@@ -120,25 +120,25 @@ int serparser_parse(void)
 
				#endif
 
				setParserState(STATE_RESET);
 
				return PARSERESULT_NODATA; // no valid start bit; better luck next time. run the function the next time around the main loop.
 
			}
 
		}
 
		
 
		// Get payload type ID
 
		else if(parserState == STATE_GETDATATYPE)
 
		{
 
			#ifdef DEBUG
 
			serial0_sendString("type\r\n");
 
			#endif
 
			receivedPayloadType = byte; // Store the type of data receiving
 
			receivedPayloadType = byte - 0x30; // Store the type of data receiving
 
			checksumCalc += byte;
 
			setParserState(STATE_GETDATA);
 
		}
 
		
 
		// Get payload data
 
		else if(parserState == STATE_GETDATA)
 
		{		
 
			if (byte == ']') // End of frame
 
			{
 
				#ifdef DEBUG
 
				serial0_sendString("eof\r\n");
 
				sprintf(debugBuff, "%d B, sum=%d\r\n", payloadLength, checksumCalc);
 
@@ -185,25 +185,26 @@ int serparser_parse(void)
 
				#ifdef DEBUG
 
				serial0_sendString("check\r\n");
 
				#endif
 
				setParserState(STATE_RESET);
 
				return PARSERESULT_PARSEOK;
 
			}
 
			else {
 
				#ifdef DEBUG
 
				serial0_sendString("bcheck\r\n");
 
				#endif
 
				setParserState(STATE_RESET);
 
				
 
				return PARSERESULT_FAIL;
 
				return PARSERESULT_PARSEOK;
 
				// !!!!!!!!!!!!!DEBUGGGGG ignore checksum ///// return PARSERESULT_FAIL;
 
			}
 
			
 
			/*
 
			if(bufferParsePosition == bufferDataPosition)
 
			{
 
				// We are at the end of the line. No more data to parse.
 
				setParserState(STATE_RESET);
 
				return PARSERESULT_PARSEOK;
 
			}
 
			else
 
			{
 
				setParserState(STATE_RESET);
master/master/lib/slavesensors.c
Show inline comments
 
@@ -15,66 +15,59 @@
 
#include "../config.h"
 
#include "serial.h"
 
#include "serparser.h"
 
#include "slavesensors.h"
 
#include "led.h"
 
#include "looptime.h"
 
#include <util/delay.h>
 
#include <avr/wdt.h>
 

	
 
uint8_t currentSlave = 0;
 
uint8_t currentSlaveSensor = 0;
 
 
uint16_t slaves[MAX_SLAVES][MAX_SLAVE_SENSORS];
 
 
bool requesting = false;
 
 
void slavesensors_setup() 
 
{
 
 
	
 
}
 

	
 
 
#define DEBUG_NETWORKSCAN
 
 
char* bufPtr = 0x00;
 
char debugBuf[64];
 
char slaveAddressLow[6][9];
 
char slaveAddressHigh[6][9];
 
char slaveAddressLow[MAX_NUM_SLAVES][9];
 
char slaveAddressHigh[MAX_NUM_SLAVES][9];
 
uint8_t loggerIndex = 255;
 
uint8_t nodeCount = 0;
 

	
 
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();
 

	
 
	char nameString[20] = "NONE";
 
	
 
	char slaveNames[6][16]; // Hold 16-char addresses of max 6 nodes, we only need them for debug so they are local 
 
	
 
	
 
	char slaveNames[MAX_NUM_SLAVES][16]; // Hold 16-char addresses of max MAX_NUM_SLAVES nodes, local so the memory can be reused
 
	
 
	// wait for OK
 
	//todo
 
	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 > 5000) {
 
				led_errorcode(ERROR_XBEETIMEOUT);
 
				return;
 
@@ -96,25 +89,25 @@ void slavesensors_network_scan() {
 
				strcpy(slaveAddressHigh[nodeCount], bufPtr);
 
			}
 
			else if(lineCount == 2) {
 
				strcpy(slaveAddressLow[nodeCount], bufPtr);
 
			}
 
			else if(lineCount == 3) {
 
				strcpy(nameString, bufPtr);
 
				strcpy(slaveNames[nodeCount], bufPtr);
 
			}
 
			
 
			// If we've finished one chunk (including the newline after it). Can't be else if because it controls increment.
 
			if(lineCount == 9) {
 
				// bufPtr should be null at this point, because we read in a newlinem after one chunk
 
				// bufPtr should be null at this point, because we read in a newline after one chunk
 
				nodeCount++;
 
				lineCount = 0;
 
			}
 
			else {
 
				lineCount++;
 
			}
 

	
 
		}		
 

	
 
		slavesensors_exitAT();
 

	
 
	}
 
@@ -130,33 +123,36 @@ void slavesensors_network_scan() {
 
			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\r\n", slaveNames[i],slaveAddressHigh,slaveAddressLow[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;
 
		}
 
	}
 
	
 
	slavesensors_selectlogger();
 
	
 
@@ -236,97 +232,110 @@ int xbeeIsOk()
 
	char* tmppntr = serial0_readLine();
 
	if(strcmp(tmppntr, "OK") == 0)
 
	{
 
		return 0;
 
	}
 
	else
 
	{
 
		led_errorcode(ERROR_NOXBEE);
 
		return 1;
 
	}
 
}
 
 
 
 
bool slavesensors_isrequesting() 
 
{
 
	return requesting;	
 
}
 
 
void slavesensors_startprocess() 
 
{
 
	requesting = true;
 
	slavesensors_request();		
 
}
 
 
// TODO: inline. static.
 
void slavesensors_request() 
 
{
 
	//slavesensors_selectnode(currentSlave);
 
	serial_sendCommand("@"); // Request data!
 
}
 
 
 
int numValues = 0; // number of values that the slave is about to send (testing)
 
int 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.
 
	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)
 
	{
 
		// 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);
 
		
 
		// Store data in structure
 
		//sensordata_set(slaves[currentSlave][currentSlaveSensor], parsedVal);
 
		
 
		// If we finished all sensors for all slaves
 
		if(currentSlave >= nodeCount && currentSlaveSensor >= numValues)
 
		{
 

	
 
		// Special case for slave telling us how many things we're about to get		
 
		if(type + 0x30 == '@') {
 
			serial0_sendString("Got an awesome count!\r\n");
 
			serial0_sendChar(parsedVal + 0x30);
 
			serial0_sendString("\r\n");
 
			numReadingsToExpect = parsedVal;
 
			currentSlave = 0;
 
			currentSlaveSensor = 0;
 
			requesting = false;
 
			requesting = true;
 
		}
 
		// If we finished up one slave, go to the next
 
		else if(currentSlaveSensor >= numValues) 
 
		{
 
			currentSlave++;
 
			currentSlaveSensor = 0;
 
			requesting = true;
 
			slavesensors_request();
 
		}
 
		// If we haven't finished a slave (or all of them), just get the next sensor of the current slave
 
		else
 
		{
 
			// request data for the current sensor of the current slave
 
			currentSlaveSensor++;
 
			requesting = true;
 
			slavesensors_request();	
 
		else {
 
		
 
			// Store data in structure
 
			sensordata_set(currentSlave,type,parsedVal);
 
			serial0_sendString("Stored some sexy data!\r\n");
 
		
 
			// If we finished all sensors for all slaves
 
			if(currentSlave >= nodeCount && currentSlaveSensor >= numReadingsToExpect)
 
			{
 
				currentSlave = 0;
 
				currentSlaveSensor = 0;
 
				requesting = false;
 
			}
 
			// If we finished up one slave, go to the next
 
			else if(currentSlaveSensor >= (numReadingsToExpect-1)) 
 
			{
 
				currentSlave++;
 
				currentSlaveSensor = 0;
 
				requesting = true;
 
				slavesensors_request();
 
			}
 
			// If we haven't finished a slave (or all of them), just get the next sensor of the current slave
 
			else
 
			{
 
				// 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
 
		}			
 
	}
 
	
 
	
0 comments (0 inline, 0 general)