Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: BLE_API mbed nRF51822 MbedJSONValue
Revision 2:6c45738bba43, committed 2017-07-24
- Comitter:
- giowild
- Date:
- Mon Jul 24 09:36:09 2017 +0000
- Parent:
- 1:ff6ec7837f46
- Commit message:
- initial working version includes:; - changing sampling interval for each pin; - changing delta thresold for each pin; - set pin to group
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MbedJSONValue.lib Mon Jul 24 09:36:09 2017 +0000 @@ -0,0 +1,1 @@ +https://mbed.org/users/samux/code/MbedJSONValue/#10a99cdf7846
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Queue.h Mon Jul 24 09:36:09 2017 +0000
@@ -0,0 +1,126 @@
+// downloaded from: https://gist.github.com/ArnonEilat/4471278
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#define TRUE 1
+#define FALSE 0
+#define QUEUE_STRING_LENGTH 40
+
+/* a link in the queue, holds the info and point to the next Node*/
+typedef struct {
+ int length;
+ char payload[QUEUE_STRING_LENGTH-1]; // null-terminated string, max 256 characters long, this may be JSON or any other format, depending on the application
+} DATA;
+
+typedef struct Node_t {
+ DATA data;
+ struct Node_t *prev;
+} NODE;
+
+/* the HEAD of the Queue, hold the amount of node's that are in the queue*/
+typedef struct Queue {
+ NODE *head;
+ NODE *tail;
+ int size;
+ int limit;
+} Queue;
+
+Queue *ConstructQueue(int limit);
+void DestructQueue(Queue *queue);
+int Enqueue(Queue *pQueue, NODE *item);
+NODE *Dequeue(Queue *pQueue);
+int isEmpty(Queue* pQueue);
+
+Queue *ConstructQueue(int limit) {
+ Queue *queue = (Queue*) malloc(sizeof (Queue));
+ if (queue == NULL) {
+ return NULL;
+ }
+ if (limit <= 0) {
+ limit = 65535;
+ }
+ queue->limit = limit;
+ queue->size = 0;
+ queue->head = NULL;
+ queue->tail = NULL;
+
+ return queue;
+}
+
+void DestructQueue(Queue *queue) {
+ NODE *pN;
+ while (!isEmpty(queue)) {
+ pN = Dequeue(queue);
+ free(pN);
+ }
+ free(queue);
+}
+
+int Enqueue(Queue *pQueue, NODE *item) {
+ /* Bad parameter */
+ if ((pQueue == NULL) || (item == NULL)) {
+ return FALSE;
+ }
+ // if(pQueue->limit != 0)
+ if (pQueue->size >= pQueue->limit) {
+ return FALSE;
+ }
+ /*the queue is empty*/
+ item->prev = NULL;
+ if (pQueue->size == 0) {
+ pQueue->head = item;
+ pQueue->tail = item;
+
+ } else {
+ /*adding item to the end of the queue*/
+ pQueue->tail->prev = item;
+ pQueue->tail = item;
+ }
+ pQueue->size++;
+ return TRUE;
+}
+
+NODE * Dequeue(Queue *pQueue) {
+ /*the queue is empty or bad param*/
+ NODE *item;
+ if (isEmpty(pQueue))
+ return NULL;
+ item = pQueue->head;
+ pQueue->head = (pQueue->head)->prev;
+ pQueue->size--;
+ return item;
+}
+
+int isEmpty(Queue* pQueue) {
+ if (pQueue == NULL) {
+ return FALSE;
+ }
+ if (pQueue->size == 0) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+/*
+int main() {
+ int i;
+ Queue *pQ = ConstructQueue(7);
+ NODE *pN;
+
+ for (i = 0; i < 9; i++) {
+ pN = (NODE*) malloc(sizeof (NODE));
+ pN->data.info = 100 + i;
+ Enqueue(pQ, pN);
+ }
+
+ while (!isEmpty(pQ)) {
+ pN = Dequeue(pQ);
+ printf("\nDequeued: %d", pN->data);
+ free(pN);
+ }
+ DestructQueue(pQ);
+ return (EXIT_SUCCESS);
+}
+
+*/
\ No newline at end of file
--- a/main.cpp Mon Mar 27 12:04:16 2017 +0000
+++ b/main.cpp Mon Jul 24 09:36:09 2017 +0000
@@ -16,6 +16,11 @@
#include "mbed.h"
#include "ble/BLE.h"
+//#include "UARTService.h"
+#include "Queue.h"
+
+
+//#define MAX_REPLY_LEN (UARTService::BLE_UART_SERVICE_MAX_DATA_LEN)
#define BLE_UUID_TXRX_SERVICE 0x0000 /**< The UUID of the Nordic UART Service. */
#define BLE_UUID_TX_CHARACTERISTIC 0x0002 /**< The UUID of the TX Characteristic. */
@@ -31,7 +36,15 @@
#define PIN_SERVO 4 // digital pin in Servo output mode
#define PIN_NOTSET 5 // pin not set
+#define NO_GROUP 0 // no_group means that current pin is sampled and transmitted individually
+
+
+#define ANALOG_MAX_VALUE 1024 // this is uint16 max value: 65535
+#define DEFAULT_SAMPLING_INTERVAL 1000 // 1 second
+#define DEFAULT_DELTA 10 // this is uint16 in range [0-65535], 655 is 1% delta
+
BLE ble;
+Queue *recvQueue = NULL, *toSendQueue =NULL;
// The Nordic UART Service
static const uint8_t uart_base_uuid[] = {0x71, 0x3D, 0, 0, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
@@ -47,17 +60,33 @@
GattCharacteristic rxCharacteristic (uart_rx_uuid, rxPayload, 1, TXRX_BUF_LEN, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
GattCharacteristic *uartChars[] = {&txCharacteristic, &rxCharacteristic};
GattService uartService(uart_base_uuid, uartChars, sizeof(uartChars) / sizeof(GattCharacteristic *));
+//UARTService *m_uart_service_ptr;
+
static const int maxPins = 30;
uint8_t pinTypes[maxPins];
+uint8_t pinGroups[maxPins];
uint16_t prevValues[maxPins];
+int pinSamplingIntervals[maxPins];
+int pinTimers[maxPins];
+uint16_t pinDelta[maxPins];
+
DigitalInOut digitals[] = {P0_0,P0_7,P0_8,P0_9,P0_10,P0_11,P0_15,P0_19,P0_28,P0_29};
int mapDigitals[] = { 0,-1,-1,-1,-1,-1,-1, 1,2,3,4,5,-1,-1,-1, 6,-1,-1,-1, 7,-1,-1,-1,-1,-1,-1,-1,-1, 8, 9,-1};
AnalogIn analogs[] = {P0_1, P0_2, P0_3, P0_4, P0_5, P0_6};
int mapAnalogs[] = {-1, 0, 1, 2, 3, 4, 5,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
+
+void enqueueItem(Queue *queue, uint8_t *buf, int len) {
+ NODE *item = NULL;
+ item = (NODE*) malloc(sizeof (NODE));
+ memcpy(item->data.payload, buf, len);
+ item->data.length = len;
+ Enqueue(queue, item);
+}
+
void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
{
//pc.printf("Disconnected \r\n");
@@ -65,23 +94,61 @@
ble.startAdvertising();
}
-bool initPin(int pin, uint8_t type){
- bool ret=false;
- if (pin>=0 && pin<31) { // "initPin(): Pin number out of bounds"
- if ((type==PIN_INPUT||type==PIN_OUTPUT) && mapDigitals[pin]>=0) {
- if (type==PIN_INPUT) digitals[mapDigitals[pin]].input(); // initialize as input
- if (type==PIN_OUTPUT) digitals[mapDigitals[pin]].output(); // initialize as input
- pinTypes[pin] = type; // mark the pin as initialized
- ret =true;
- } else if (type==PIN_ANALOG && mapAnalogs[pin]>=0) {
- pinTypes[pin] = type; // mark the pin as initialized
- ret =true;
+
+NODE *enqItem = NULL;
+int bytesCmd = 0;
+bool endsOnNewLine = true;
+#define NOT_FOUND -1
+
+void WrittenHandler(const GattWriteCallbackParams *params)
+{
+ uint8_t buf[TXRX_BUF_LEN];
+ uint16_t bytesRead, i;
+
+ if (params->handle == txCharacteristic.getValueAttribute().getHandle()) {
+ ble.readCharacteristicValue(params->handle, buf, &bytesRead);
+
+ if (enqItem == NULL){
+ endsOnNewLine = buf[0]=='{';
}
- }
- return ret;
+
+ if (!endsOnNewLine) {
+ enqueueItem(recvQueue, buf, bytesRead);
+ } else {
+ for (i=0; i<bytesRead; i++) {
+ if (endsOnNewLine && (buf[i]=='\n' || bytesCmd>QUEUE_STRING_LENGTH)) {
+ if (enqItem != NULL && enqItem->data.length>0) {
+ // push string to queue
+ Enqueue(recvQueue, enqItem);
+ }
+ enqItem = NULL;
+ } else {
+ // enqueue character
+ if (enqItem == NULL) {
+ enqItem = (NODE*) malloc(sizeof (NODE));
+ bytesCmd = 0;
+ }
+ enqItem->data.payload[bytesCmd++]=buf[i];
+ enqItem->data.length = bytesCmd;
+ }
+ }
+ }
+ }
}
-uint16_t readPin(int pin) {
+uint16_t readPin(uint8_t pin) {
+ uint8_t mode = pinTypes[pin];
+ if (mode==PIN_INPUT) { // exists and is initialized as digital output
+ return digitals[mapDigitals[pin]].read()==0?0:ANALOG_MAX_VALUE;
+ } else if (mode==PIN_OUTPUT) { // exists and is initialized as digital output
+ return digitals[mapDigitals[pin]].read()==0?0:ANALOG_MAX_VALUE;
+ } else if (mode==PIN_ANALOG) { // exists and is initialized as digital output
+ return analogs[mapAnalogs[pin]].read_u16(); // 10 bits only
+ }
+ return 0;
+}
+
+uint16_t readPinOld(int pin) {
uint8_t mode = pinTypes[pin];
if (mode==PIN_INPUT) { // exists and is initialized as digital output
mode = 0;
@@ -100,109 +167,43 @@
return 0;
}
-void sendPinValue(int pin, uint16_t value) {
+void sendPinValue(uint8_t pin, uint16_t value) {
uint8_t buf[TXRX_BUF_LEN];
buf[0]='G';
buf[1]=pin;
- buf[2]=(uint8_t)(value>>8); buf[3]=(uint8_t)value;
- ble.updateCharacteristicValue(rxCharacteristic.getValueAttribute().getHandle(), buf, 4);
+ buf[2]=(uint8_t)(value>>8);
+ buf[3]= (uint8_t) ((value<<8)>>8);
+ enqueueItem(toSendQueue, buf, 4);
+ /*int len = sprintf((char *)buf,"{\"pin\":%d,\"v\":%4.3f}",pin,(float)value/(float)ANALOG_MAX_VALUE);
+ enqueueItem(toSendQueue,buf, len);*/
+
prevValues[pin] = value;
}
-void parseRedBearCmd(){
- uint8_t buf[TXRX_BUF_LEN];
- memset(buf, 0, TXRX_BUF_LEN);
-
- uint8_t startOffset = txPayload[0]==0?1:0;
- uint8_t index = startOffset;
- uint8_t cmd = txPayload[index++], pin=txPayload[index++], mode=PIN_NOTSET;
- pin = pin>=48?pin-48:pin;
- switch (cmd) {
- case 'Z':sendPinValue(pin,readPin(pin));
- break;
- case 'X':initPin(7, PIN_OUTPUT);
- break;
- case 'Y':uint8_t value2write = txPayload[index++]-48;
- if (mapDigitals[pin]>=0) {
- digitals[mapDigitals[pin]].write(value2write==0?0:1);
- sendPinValue(pin,readPin(pin));
- }
- break;
-
- case 'M': //pc.printf("Querying pin %u mode\n",pin);
- buf[0]=cmd;
- buf[1]=pin;
- buf[2]=pinTypes[pin];
- ble.updateCharacteristicValue(rxCharacteristic.getValueAttribute().getHandle(), buf, 3);
- break;
-
- case 'S': // set pin mode
- mode = txPayload[index++];
- mode = mode>=48?mode-48:mode;
- if (initPin(pin, mode)) { // analogs are already initialized
- sendPinValue(pin,readPin(pin));
- }
- break;
-
- case 'G': //pc.printf("Reading pin %u\n",pin);
- switch (pinTypes[pin]) {
- case PIN_INPUT:
- case PIN_ANALOG:
- sendPinValue(pin,readPin(pin));
- break;
- case PIN_OUTPUT: // TODO: send warning pin not readable (is an output)
- default: // TODO: send warning pin not initialized
- buf[0]=PIN_NOTSET;
- buf[1]=PIN_NOTSET;
- buf[2]=PIN_NOTSET;
- ble.updateCharacteristicValue(rxCharacteristic.getValueAttribute().getHandle(), buf, 3);
- break;
- }
- break;
-
- case 'T':
- switch (pinTypes[pin]) {
- case PIN_OUTPUT:
- uint8_t value2write = txPayload[index++];
- if (mapDigitals[pin]>=0) {
- digitals[mapDigitals[pin]].write(value2write==0?0:1);
- sendPinValue(pin,readPin(pin));
- }
- break;
- case PIN_INPUT: // TODO: send warning pin not writable (is an input)
- case PIN_ANALOG: // TODO: send warning pin not writable (is an input)
- default: // TODO: send warning pin not initialized
- buf[0]='T';
- buf[1]='T';
- buf[2]='T';
- ble.updateCharacteristicValue(rxCharacteristic.getValueAttribute().getHandle(), buf, 3);
- break;
- }
- break;
-
- default:
- // echo received buffer
- ble.updateCharacteristicValue(rxCharacteristic.getValueAttribute().getHandle(), &txPayload[startOffset], strlen((char *)&txPayload[startOffset])); // FIXME
- break;
- }
+void sendGroup(uint8_t groupno) {
+ uint8_t buf[TXRX_BUF_LEN], i=0;
+ buf[i++]='G';
+ for (uint8_t pin=0; pin<maxPins;pin++){
+ if (pinGroups[pin]==groupno) {
+ uint16_t value = readPin(pin);
+ buf[i++] = pin;
+ buf[i++] = (uint8_t)(value>>8);
+ buf[i++] = (uint8_t) ((value<<8)>>8);
+ prevValues[pin] = value;
+ }
+ }
+ if (i>1) { // at least 1 pin value to send
+ enqueueItem(toSendQueue, buf, i);
+ }
}
-
-void WrittenHandler(const GattWriteCallbackParams *Handler)
-{
- uint8_t buf[TXRX_BUF_LEN];
- uint16_t bytesRead;
-
- if (Handler->handle == txCharacteristic.getValueAttribute().getHandle()) //only if empty
- {
- ble.readCharacteristicValue(txCharacteristic.getValueAttribute().getHandle(), buf, &bytesRead);
- memset(txPayload, 0, TXRX_BUF_LEN);
- memcpy(txPayload, buf, TXRX_BUF_LEN);
-
- ble.updateCharacteristicValue(rxCharacteristic.getValueAttribute().getHandle(), buf, bytesRead);
- parseRedBearCmd();
+bool isInputPin(uint8_t pin) {
+ if (pin<maxPins){
+ uint8_t type = pinTypes[pin];
+ return type==PIN_INPUT||type==PIN_ANALOG;
}
+ return false;
}
void m_status_check_handle(void)
@@ -218,15 +219,290 @@
}
}
+
+static volatile int gcd=-1;
+Ticker *pTicker;
+//Timeout timeout;
+static volatile bool recalcTimer = false;
+static volatile bool triggerSensorPolling = false;
+static volatile bool gcdChanged =false;
+
+int calc_gcd(int n1,int n2) {
+ int lgcd=1;
+ for(int i=2; i <= n1 && i <= n2; ++i)
+ {
+ // Checks if i is factor of both integers
+ if(n1%i==0 && n2%i==0)
+ lgcd = i;
+ }
+ return lgcd;
+}
+
+void check_pin_changed(void)
+{
+ uint8_t buf[QUEUE_STRING_LENGTH];
+ if (gcd>0) {
+ for (int pin=0; pin<maxPins;pin++){
+ if (isInputPin(pin)) {
+ if (pinTimers[pin] < 0) {
+ pinTimers[pin] = pinSamplingIntervals[pin];
+ } else {
+ pinTimers[pin]-=gcd;
+ }
+ if (pinTimers[pin]==0) {
+ pinTimers[pin] = pinSamplingIntervals[pin];
+ uint16_t value = readPin(pin);
+ if (abs(prevValues[pin]-value) >= pinDelta[pin]) {
+ if (pinGroups[pin]!=NO_GROUP) { // enqueue sending operation for group
+ int len = sprintf((char *)buf,"R%c",pinGroups[pin]);
+ enqueueItem(recvQueue, buf, len);
+ } else { // send the pin
+ sendPinValue(pin,value);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void calc_timer_interval()
+{
+ gcd = -1;
+ for (int pin=0; pin<maxPins;pin++){
+ if (isInputPin(pin) && pinSamplingIntervals[pin]>0) {
+ uint8_t buf[TXRX_BUF_LEN];
+ int len = sprintf((char *)buf,"TIMER %d@%d",pin,pinSamplingIntervals[pin]);
+ //int len = sprintf((char *)buf,"check-gcd");
+ enqueueItem(toSendQueue, buf, len);
+
+ if (gcd==-1) {
+ gcd = pinSamplingIntervals[pin];
+ } else {
+ gcd = calc_gcd(gcd,pinSamplingIntervals[pin]);
+ }
+ }
+ }
+}
+
+bool initPin(uint8_t pin, uint8_t type){
+ bool ret=false,wasset=true,armTimer=false;
+
+ //uint8_t buf[TXRX_BUF_LEN];
+ //buf[0]='Y';buf[1]=pin;buf[2]=type;
+ //int len = sprintf((char *)buf,"ASD%d-%c",pin,pin);
+ //enqueueItem(toSendQueue, buf, 3);
+
+ if (pin<maxPins) { // "initPin(): Pin number out of bounds"
+ wasset = pinTypes[pin]!=PIN_NOTSET;
+ if ((type==PIN_INPUT||type==PIN_OUTPUT) && mapDigitals[pin]>=0) {
+ if (type==PIN_INPUT) digitals[mapDigitals[pin]].input(); // initialize as input
+ if (type==PIN_OUTPUT) digitals[mapDigitals[pin]].output(); // initialize as input
+ pinTypes[pin] = type; // mark the pin as initialized
+ ret =true;
+ } else if (type==PIN_ANALOG && mapAnalogs[pin]>=0) {
+ pinTypes[pin] = type; // mark the pin as initialized
+ ret =true;
+ }
+ if (!wasset && ret && (type==PIN_INPUT||type==PIN_ANALOG)) armTimer=true;
+ }
+ if (armTimer) {
+ pinSamplingIntervals[pin] = DEFAULT_SAMPLING_INTERVAL;
+ //pinTimers[pin]=pinSamplingIntervals[pin];
+ recalcTimer = true;
+ }
+
+ return ret;
+}
+
+bool initPin(uint8_t pin, uint8_t type, uint8_t group){
+ bool ret = initPin(pin, type);
+ if (ret){
+ pinGroups[pin]=group;
+ }
+ return ret;
+}
+
+void changeDelta(uint8_t pin, uint16_t delta) {
+ uint8_t buf[TXRX_BUF_LEN];
+ int len = sprintf((char *)buf,"DELTA %d@%d",pin,delta);
+ enqueueItem(toSendQueue, buf, len);
+
+ //float fdelta = delta / ANALOG_MAX_VALUE;
+ if (delta > ANALOG_MAX_VALUE) delta=ANALOG_MAX_VALUE;
+ if (isInputPin(pin)) {
+ pinDelta[pin] = delta;
+ }
+}
+
+void changeDeltaPercent(uint8_t pin, float fdelta) {
+ changeDelta(pin, (uint16_t)(fdelta*ANALOG_MAX_VALUE));
+}
+void changeSamplingInterval(uint8_t pin, int interval) {
+ if (isInputPin(pin)) {
+ pinSamplingIntervals[pin]= interval;
+ recalcTimer = true;
+ }
+}
+
+bool writeDigital(uint8_t pin, bool value){
+ if (mapDigitals[pin]>=0) {
+ digitals[mapDigitals[pin]].write(value?1:0);
+ //sendPinValue(pin,readPin(pin));
+ }
+}
+
+void parseRedBearCmd(uint8_t* cmdString){
+ uint8_t buf[TXRX_BUF_LEN];
+ memset(buf, 0, TXRX_BUF_LEN);
+ int len=0, scanned=-1, sampling=-1;
+ float fdelta=-1;
+
+ uint8_t startOffset = cmdString[0]==0?1:0;
+ uint8_t index = startOffset;
+ uint8_t cmd = cmdString[index++], pin=cmdString[index++], mode=PIN_NOTSET, group=NO_GROUP;
+ pin = pin>=48?pin-48:pin;
+
+ switch (cmd) {
+ case '{':
+ //snprintf((char*) buf, MAX_REPLY_LEN, "ERROR: Unknown char\n");
+ //m_uart_service_ptr->writeString((char*)buf);
+ break;
+ case 'Y':
+ uint8_t value2write = cmdString[index++]-48;
+ value2write = value2write>=48?value2write-48:value2write;
+ writeDigital(pin,value2write!=0);
+ break;
+
+ case 'M': //pc.printf("Querying pin %u mode\n",pin);
+ buf[0]=cmd;buf[1]=pin;buf[2]=pinTypes[pin];
+ enqueueItem(toSendQueue, buf, 3);
+ break;
+
+ case 'S': // set pin mode
+ mode = cmdString[index++];
+ mode = mode>=48?mode-48:mode;
+ group = cmdString[index++];
+ if (initPin(pin, mode, group)) { // analogs are already initialized
+ //if (initPin(pin, mode)) { // analogs are already initialized
+ sendPinValue(pin,readPin(pin));
+ }
+ break;
+
+ case 'D': // delta to consider value changed (as percentage [0-1] of Voltage range)
+ scanned = sscanf( (char *)&cmdString[2], "%f", &fdelta);
+
+ if (scanned==1 && fdelta>=0 && fdelta<=1) {
+ len = sprintf((char *)buf,"DELTA%d@%f",(int)pin,fdelta);
+ enqueueItem(toSendQueue, buf, len);
+ changeDeltaPercent(pin, fdelta);
+ /*changeDelta ( pin,((uint16_t)cmdString[index+0]) << 8 |
+ ((uint16_t)cmdString[index+1]) );*/
+ } else {
+ len = sprintf((char *)buf,"DELTA%d@ERR",(int)pin);
+ enqueueItem(toSendQueue, buf, len);
+ }
+ break;
+
+ case 'I': // sampling interval
+ scanned = sscanf( (char *)&cmdString[2], "%d", &sampling);
+
+ if (scanned==1 && sampling>=0) {
+ len = sprintf((char *)buf,"SAMPL%d@%d",(int)pin,sampling);
+ enqueueItem(toSendQueue, buf, len);
+ changeSamplingInterval( pin, sampling);
+ /*changeSamplingInterval( pin,((int)cmdString[index+0]) << 24 |
+ ((int)cmdString[index+1]) << 16 |
+ ((int)cmdString[index+2]) << 8 |
+ ((int)cmdString[index+3]) );*/
+ } else {
+ len = sprintf((char *)buf,"SAMPL%d@ERR",(int)pin);
+ enqueueItem(toSendQueue, buf, len);
+ }
+ break;
+
+ case 'G': //pc.printf("Reading pin %u\n",pin);
+ switch (pinTypes[pin]) {
+ case PIN_INPUT:
+ case PIN_ANALOG:
+ sendPinValue(pin,readPin(pin));
+ break;
+ case PIN_OUTPUT: // TODO: send warning pin not readable (is an output)
+ default: // TODO: send warning pin not initialized
+ buf[0]=PIN_NOTSET;buf[1]=PIN_NOTSET;buf[2]=PIN_NOTSET;
+ enqueueItem(toSendQueue, buf, 3);
+ break;
+ }
+ break;
+
+ case 'T':
+ switch (pinTypes[pin]) {
+ case PIN_OUTPUT:
+ uint8_t value2write = cmdString[index++];
+ if (mapDigitals[pin]>=0) {
+ digitals[mapDigitals[pin]].write(value2write==0?0:1);
+ sendPinValue(pin,readPin(pin));
+ }
+ break;
+ case PIN_INPUT: // TODO: send warning pin not writable (is an input)
+ case PIN_ANALOG: // TODO: send warning pin not writable (is an input)
+ default: // TODO: send warning pin not initialized
+ buf[0]='T';buf[1]='T';buf[2]='T';
+ enqueueItem(toSendQueue, buf, 3);
+ break;
+ }
+ break;
+ case 'R':
+ // pin variable contains the group, not the pin number
+ sendGroup(pin);
+ break;
+ default:
+ // echo received buffer
+ enqueueItem(toSendQueue, &cmdString[startOffset], strlen((char *)&cmdString[startOffset]));
+ break;
+ }
+}
+
+
+void triggerSensor(){
+ triggerSensorPolling=true;
+}
+
+
+void changeGcdTiming(){
+ /*if (gcdChanged) {
+ gcdChanged =false;
+ if (gcd>0) {
+ pTicker->attach(NULL,5);
+ pTicker->attach(triggerSensor, 0.001*gcd);
+ } else {
+ pTicker->attach(NULL,5);
+ }
+ }*/
+
+ uint8_t buf[TXRX_BUF_LEN];
+ int len = sprintf((char *)buf,"check-gcd %d",gcd);
+ enqueueItem(toSendQueue, buf, len);
+}
+
+
int main(void)
{
+
for (int i=0;i<maxPins;i++) {
pinTypes[i] = PIN_NOTSET;
prevValues[i] = 0;
+ pinSamplingIntervals[i] = -1;
+ pinTimers[i]=-1;
+ pinDelta[i]=DEFAULT_DELTA;
+ pinGroups[i]=NO_GROUP;
}
+
+ initPin(7,PIN_OUTPUT);
+ initPin(28,PIN_OUTPUT);
+ writeDigital(7,true);
+ writeDigital(28,false);
- //memset(txPayload, 0, TXRX_BUF_LEN);
-
ble.init();
ble.onDisconnection(disconnectionCallback);
ble.onDataWritten(WrittenHandler);
@@ -245,12 +521,81 @@
ble.startAdvertising();
+ //ticker.attach(m_status_check_handle, 0.2);
+
+ // Create a UARTService object (GATT stuff).
+ //UARTService myUartService(ble);
+ //m_uart_service_ptr = &myUartService;
+
Ticker ticker;
- ticker.attach(m_status_check_handle, 0.2);
+ //pTicker = &ticker;
+
+ //Ticker pinTicker;
+ //pinTicker.attach(triggerSensor, 5);
+
+ Ticker gcdTicker;
+ gcdTicker.attach(changeGcdTiming, 5);
+
+ recvQueue = ConstructQueue(40);
+ toSendQueue = ConstructQueue(40);
+
+ uint8_t buf[QUEUE_STRING_LENGTH];
+ NODE *deqItem = NULL;
+ /*
+ // set pin 7 as VCC and pin 28 as GND
+ int len = sprintf((char *)buf,"S%c%c",7,1);
+ enqueueItem(recvQueue, buf, len);
+ len = sprintf((char *)buf,"S%c%c",28,1);
+ enqueueItem(recvQueue, buf, len);
+ len = sprintf((char *)buf,"Y%c%c",7,'1');
+ enqueueItem(recvQueue, buf, len);
+ len = sprintf((char *)buf,"Y%c%c",28,'0');
+ enqueueItem(recvQueue, buf, len);*/
while(1)
{
- ble.waitForEvent();
+ if (ble.getGapState().connected) {
+ if (recalcTimer) {
+ recalcTimer =false;
+ calc_timer_interval();
+ //gcdChanged =true;
+ if (gcd>0) {
+ ticker.attach(NULL,5);
+ ticker.attach(triggerSensor, 0.001*gcd);
+ } else {
+ ticker.attach(NULL,5);
+ }
+ } else if (!isEmpty(toSendQueue)) {
+ //while (!isEmpty(toSendQueue)) {
+ deqItem = Dequeue(toSendQueue);
+ //memset(buf, 0, QUEUE_STRING_LENGTH); // useless
+ memcpy(buf, (uint8_t *)deqItem->data.payload, deqItem->data.length);
+ ble.updateCharacteristicValue(rxCharacteristic.getValueAttribute().getHandle(), buf, deqItem->data.length);
+ //ble.updateCharacteristicValue(m_uart_service_ptr->getRXCharacteristicHandle(), buf, deqItem->data.length);
+ free(deqItem);
+ //}
+ } else if (!isEmpty(recvQueue)) {
+ //if (!isEmpty(recvQueue)) {
+ deqItem = Dequeue(recvQueue);
+ memset(buf, 0, QUEUE_STRING_LENGTH); // maybe useless: TO CHECK its handling in parseRedBearCmd
+ memcpy(buf, (uint8_t *)deqItem->data.payload, deqItem->data.length);
+ //ble.updateCharacteristicValue(m_uart_service_ptr->getRXCharacteristicHandle(), buf, deqItem->data.length);
+ //ble.updateCharacteristicValue(rxCharacteristic.getValueAttribute().getHandle(), buf, deqItem->data.length);
+ parseRedBearCmd(buf);
+ free(deqItem);
+ //}
+ //} else if (!isEmpty(toSendQueue)) {
+ } else if (triggerSensorPolling) {
+ triggerSensorPolling = false;
+ check_pin_changed();
+ } else {
+ ble.waitForEvent();
+ }
+ } else {
+ ble.waitForEvent();
+ }
+
+
}
}