Paolo
ieri sera abbiamo visto come collegare il modulo bluetooth alla tua apps nel cui sviluppo però non hai considerato la possibilità di trasmettere stringhe per il pilotaggio di moduli di I/O o la lettura degli input analogigici di arduino.
Di seguito allego il codice relativo alla routine per la lettura dello stream di tutte le porte seriali del mega 2560 (basta attivare i controlli dello stream nel modo più opportuno) e la routine per l'acquisizione dei dati analogi del 2560. Utilizzando gli stream in modo corretto si riescono a passare più interrogazioni in contemporanea da bluetooth e seriale in contemporanea senza degradi di prestazioni apparenti almeno per i metodi che ho implementato ed utilizzo.
Vedi tu se inserire il tutto come ampliamento di rmap o se preferisci che aggiunga il tutto come branca di sviluppo a parte.
SERIAL STREAM
#ifdef SERIALJSONRPC
// ---------------------------------------
// SERVICES - SERIAL STREAM
// ---------------------------------------
// Receiving json objects through a serial
// (0-1-2-3) or USB connection.
// -------------------------------- Create Serial Streams of JsonRPC
aJsonStream stream(&Serial);
// aJsonStream stream1(&Serial1);
// aJsonStream stream2(&Serial2);
aJsonStream stream3(&Serial3);
// -------------------------------- Create Software Serial Streams of JsonRPC
// insert available SoftwareSerial
// Object and it's stream
#endif
// ======================================================
// TRANSPORT - SERIAL
// ======================================================
// This transport set serial stream data transfer
//
// active only if JSONRPCON is defined in ardubee_config.h
#if defined (JSONRPCON)
void mgrserialjsonrpc(void)
{
#ifdef FREERAM
Serial.print(F("#free ram on mgrserialjsonrpc: "));
Serial.println(freeRam());
#endif
if (stream.available()) {
// skip any accidental whitespace like newlines
stream.skip();
} else if (stream3.available()) {
// skip any accidental whitespace like newlines
stream3.skip();
}
if (stream.available()) {
IF_SDEBUG(Serial.println(F("#Serial (0) : stream available")));
aJsonObject *msg = aJson.parse(&stream);
mgrjsonrpc(msg);
aJson.deleteItem(msg);
if (strlen(mainbuf) > 0) {
Serial.println(mainbuf);
}
if (stream.available()) {
stream.flush();
}
} else if (stream3.available()) {
IF_SDEBUG(Serial.println(F("#Serial (3): stream available")));
aJsonObject *msg = aJson.parse(&stream3);
mgrjsonrpc(msg);
aJson.deleteItem(msg);
if (strlen(mainbuf) > 0) {
Serial3.println(mainbuf);
}
if (stream3.available()) {
stream3.flush();
}
}
}
#endif
ROUTINE GETADC
// ======================================================
// METHOD - GETADC
// ======================================================
// This method read single channel:
// {"jsonrpc": "2.0", "method": "getadc", "params": [{"channel":4},{"channel":6}], "id": 0}
//
// or read all ADC channels:
// {"jsonrpc": "2.0", "method": "getadc", "params": [{"channel":9}], "id": 0}
//
// active only if USE_ADC is defined in ardubee_config.h
#if defined (USE_ADC)
// To apply this METHOD you can use the following array
// pinADC [] = {A8,A9,A10,A11,A12,A13,A14,A15} formega 2560
int getADC(aJsonObject* params)
{
// ---------------------------------------- Support varables
int analogValues[8];
int readingData = 0;
// ---------------------------------------- Get Params
aJsonObject *pinobj = params->child;
if (!pinobj) return E_INTERNAL_ERROR;
// ---------------------------------------- Make Oject result
result = aJson.createObject();
// ---------------------------------------- Loop to read params
do {
aJsonObject* adcParam = aJson.getObjectItem(pinobj, "channel");
if (!adcParam) return E_INTERNAL_ERROR;
int channelADC = adcParam -> valueint;
// ---------------------------------------- Switch to read all adc
if ((channelADC==9) && (readingData==0)){
// ---------------------------------------- Update analogValues Array
for (int i = 0; i < 8; i++) {
analogValues[i] = analogRead(i);
IF_SDEBUG(Serial.print("# ADC"+String(i)+" "));
IF_SDEBUG(Serial.print(analogValues[i]));
IF_SDEBUG(Serial.print(" "));
}
// ---------------------------------------- Make reading Object & Update result Object
// Generate message like:
// {"jsonrpc": "2.0", "result": {"ADC Values":[200, 400, 600, 800, 100, 10, 8]}, id:0 }
aJsonObject *reading = aJson.createIntArray(analogValues, 8);
aJson.addItemToObject(result, "ADC Values ", reading);
readingData++;
return E_SUCCESS;
} else if ((channelADC==9) && (readingData!=0)){
return E_INTERNAL_ERROR;
}
// ---------------------------------------- Test channelADC value
bool pinok = false;
if ((channelADC >=0) && (channelADC <8)) pinok=true;
if (!pinok) return E_INTERNAL_ERROR;
IF_SDEBUG(Serial.print(F("# ADC Channel: ")));
IF_SDEBUG(Serial.println(channelADC));
// ---------------------------------------- Update analogValues Array
analogValues[channelADC] = analogRead(pinADC [channelADC]);
// ----------------------------------------- Update ADC Array Status
//
IF_SDEBUG(Serial.print(F(" Value : ")));
IF_SDEBUG(Serial.println(analogValues[channelADC]));
// ---------------------------------------- Make reading Object & Update result Object
// Generate message like:
// {"jsonrpc": "2.0", "result":{"ADC":1, "Values": 1023, "ADC":2, "Values":100}, id:0 }
aJson.addNumberToObject(result, "ADC", channelADC);
aJson.addNumberToObject(result, "Value ", analogValues[channelADC]);
// updateRelays[requestedPin]=requestedStatus;
// ------------------------------------- Trace Frame Data
pinobj=pinobj->next;
} while ( pinobj );
return E_SUCCESS;
}
#endif
Per il bluetooth credo che possa funzionare anche il BLE di microduino devi solo gestire lo stream realtivo alla seriale cui è collegato il modulo bluetooth non importa utilizzare la libreria software serial nel caso di chip simili al 2560 credo ci sia la possibilità di trovare le porte seriali aggiuntive ed i relativi pin consultando il datasheet del microcontrollore ed utilizzarli collegandoli direttamente ai pin del modulo bluetooth ... Comunque questa è la sequenza di comandi per l'attivazione di un modulo BT su arduino (riporto la configurazione del modulo bt sulla mia itead che occupa la seriale 3 per altre configurazioni basta cambiare la porta)
// ======================================================
// FUNCTION - setupBlueToothConnection
// ======================================================
void setupBlueToothConnection()
{
Serial3.begin(38400); //Set BluetoothBee BaudRate to default baud rate 38400
Serial3.print("\r\n+STWMOD=0\r\n"); //set the bluetooth work in slave mode
//the default value set for bluetooth module name is "SeeedBTSlave"
// we have changed neme in "ArduBeeBTH"
Serial3.print("\r\n+STNA=ArduBeeBTH\r\n"); //set the bluetooth name as "ArduBeeBTH"
// or set the bluetooth name as "RmapBTH"
// Serial3.print("\r\n+STNA=RmapBTH\r\n");
Serial3.print("\r\n+STOAUT=1\r\n"); // Permit Paired device to connect me
Serial3.print("\r\n+STAUTO=0\r\n"); // Auto-connection should be forbidden here
delay(2000); // This delay is required.
Serial3.print("\r\n+INQ=1\r\n"); //make the slave bluetooth inquirable
Serial.println(" The slave bluetooth is inquirable!");
delay(2000); // This delay is required.
Serial3.flush();
}
ripeto il sistema funziona bene con json rpc. Grazie per i moduli microduino.
Sarebbe interessante se riuscissi a progettare un apps aggiuntiva (io con kyvy non mi trovo ancora a mio agio) semplice ed in grado di trasmettere solo stringhe json rpc di controllo predefinite e magari archiviabili e richiamabili dall'utente alla bisogna per gestire in modo un pò più manuale il tutto (tipo accendi un rele ... leggi un valore di adc ... setta una soglia di intervento ... archivia i dati su sd card ed altre amenità del genere) vedi tu .... se riuscissi a farlo credo che l'ambito applicativo di rmap possa divenire maggiormente interessente facendogli abbandonare la nicchia del solo seppur corretto rilevamento rilevamento meteo. (io posso pensare alla creazione dei relativi metodi di gestione delle stringhe jsonrpc)
A presto
Emme