Commit 84ad49db authored by Pedro Henrique Kopper's avatar Pedro Henrique Kopper

Add ping-pong logic and modularized InstrumentInterface

parent 159a5faf
Subproject commit cb754fd9e15cb700e5521f9323fe307549e59a29
Subproject commit 6a829cc7c094d271a50cffb86107d5b54af9df67
#include <Arduino.h>
#include "protobuf/pb.h"
#include "protobuf/pb_common.h"
#include "protobuf/pb_decode.h"
#include "protobuf/pb_encode.h"
#include "sadapmap_pb/sadapmap.pb.h"
#include "InstrumentInterface.hpp"
InstrumentInterface::InstrumentInterface(void) {};
void InstrumentInterface::init(Stream& s, req_multi_reading_callback_t cb) {
_stream = &s;
_multi_reading_cb = cb;
_stream->setTimeout(15); // Empirico. A 115200 8N1, 128 bytes demoram 10ms.
}
void InstrumentInterface::pollMulti(void) {
uint8_t buffer[128] = {0};
sadapmap_ReqMultiChannelReading req = sadapmap_ReqMultiChannelReading_init_default;
// Importante limpar o buffer antes de realizar a leitura para evitar duplicatas
_stream->flush();
uint8_t len = _stream->readBytes(buffer, sizeof(buffer));
// Segue o baile se não receber nada
if(len == 0)
return;
// Decodifica e chama o callback
pb_istream_t stream = pb_istream_from_buffer(buffer, len);
bool status = pb_decode(&stream, sadapmap_ReqMultiChannelReading_fields, &req);
_multi_reading_cb(status, &req);
}
/*
* Envia as leituras de um único canal
* Retorna se o envio foi bem sucedido (true) ou não (false)
*/
bool InstrumentInterface::sendSingleChannel(uint8_t id, float value) {
uint8_t buffer[128] = {0};
sadapmap_ChannelReading reading = sadapmap_ChannelReading_init_default;
pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
reading.id = id;
reading.value = value;
uint8_t status = pb_encode(&stream, sadapmap_ChannelReading_fields, &reading);
uint8_t message_length = stream.bytes_written;
if(status)
_stream->write(buffer, message_length);
return status;
}
/*
* Envia as leituras de um único canal
* Retorna se o envio foi bem sucedido (true) ou não (false)
*/
bool InstrumentInterface::sendMultiChannel(uint32_t *id, float *value, uint8_t count) {
uint8_t buffer[128] = {0};
sadapmap_MultiChannelReading multi = sadapmap_MultiChannelReading_init_default;
multi.channels_count = count;
for(uint8_t i = 0; i < count; i++) {
multi.channels[i] = { id[i], value[i] };
}
pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
uint8_t status = pb_encode(&stream, sadapmap_MultiChannelReading_fields, &multi);
uint8_t message_length = stream.bytes_written;
if(status)
_stream->write(buffer, message_length);
return status;
}
\ No newline at end of file
#pragma once
#include <Arduino.h>
#include "sadapmap_pb/sadapmap.pb.h"
using req_multi_reading_callback_t = void(*)(bool, sadapmap_ReqMultiChannelReading*);
using req_reading_callback_t = void(*)(bool, sadapmap_ReqChannelReading*);
class InstrumentInterface {
public:
InstrumentInterface(void);
void init(Stream&, req_multi_reading_callback_t);
void pollMulti(void);
bool sendSingleChannel(uint8_t, float);
bool sendMultiChannel(uint32_t*, float*, uint8_t);
private:
Stream *_stream;
req_reading_callback_t _reading_cb;
req_multi_reading_callback_t _multi_reading_cb;
};
\ No newline at end of file
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.3.9.3 at Mon Apr 22 16:12:54 2019. */
/* Generated by nanopb-0.3.9.3 at Wed Apr 24 16:43:21 2019. */
#include "sadapmap.pb.h"
......@@ -17,7 +17,7 @@ const pb_field_t sadapmap_ChannelReading_fields[3] = {
};
const pb_field_t sadapmap_MultiChannelReading_fields[2] = {
PB_FIELD( 1, MESSAGE , REPEATED, CALLBACK, FIRST, sadapmap_MultiChannelReading, channels, channels, &sadapmap_ChannelReading_fields),
PB_FIELD( 1, MESSAGE , REPEATED, STATIC , FIRST, sadapmap_MultiChannelReading, channels, channels, &sadapmap_ChannelReading_fields),
PB_LAST_FIELD
};
......@@ -36,9 +36,33 @@ const pb_field_t sadapmap_ReqChannelReading_fields[2] = {
};
const pb_field_t sadapmap_ReqMultiChannelReading_fields[2] = {
PB_FIELD( 1, UINT32 , REPEATED, CALLBACK, FIRST, sadapmap_ReqMultiChannelReading, id, id, 0),
PB_FIELD( 1, UINT32 , REPEATED, STATIC , FIRST, sadapmap_ReqMultiChannelReading, id, id, 0),
PB_LAST_FIELD
};
/* Check that field information fits in pb_field_t */
#if !defined(PB_FIELD_32BIT)
/* If you get an error here, it means that you need to define PB_FIELD_32BIT
* compile-time option. You can do that in pb.h or on compiler command line.
*
* The reason you need to do this is that some of your messages contain tag
* numbers or field sizes that are larger than what can fit in 8 or 16 bit
* field descriptors.
*/
PB_STATIC_ASSERT((pb_membersize(sadapmap_MultiChannelReading, channels[0]) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_sadapmap_ChannelReading_sadapmap_MultiChannelReading_sadapmap_ChannelMetadata_sadapmap_ReqChannelReading_sadapmap_ReqMultiChannelReading)
#endif
#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT)
/* If you get an error here, it means that you need to define PB_FIELD_16BIT
* compile-time option. You can do that in pb.h or on compiler command line.
*
* The reason you need to do this is that some of your messages contain tag
* numbers or field sizes that are larger than what can fit in the default
* 8 bit descriptors.
*/
PB_STATIC_ASSERT((pb_membersize(sadapmap_MultiChannelReading, channels[0]) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_sadapmap_ChannelReading_sadapmap_MultiChannelReading_sadapmap_ChannelMetadata_sadapmap_ReqChannelReading_sadapmap_ReqMultiChannelReading)
#endif
/* @@protoc_insertion_point(eof) */
/* Automatically generated nanopb header */
/* Generated by nanopb-0.3.9.3 at Mon Apr 22 16:12:54 2019. */
/* Generated by nanopb-0.3.9.3 at Wed Apr 24 16:43:21 2019. */
#ifndef PB_SADAPMAP_SADAPMAP_PB_H_INCLUDED
#define PB_SADAPMAP_SADAPMAP_PB_H_INCLUDED
#include <pb.h>
#include "../protobuf/pb.h"
/* @@protoc_insertion_point(includes) */
#if PB_PROTO_HEADER_VERSION != 30
......@@ -15,16 +15,6 @@ extern "C" {
#endif
/* Struct definitions */
typedef struct _sadapmap_MultiChannelReading {
pb_callback_t channels;
/* @@protoc_insertion_point(struct:sadapmap_MultiChannelReading) */
} sadapmap_MultiChannelReading;
typedef struct _sadapmap_ReqMultiChannelReading {
pb_callback_t id;
/* @@protoc_insertion_point(struct:sadapmap_ReqMultiChannelReading) */
} sadapmap_ReqMultiChannelReading;
typedef struct _sadapmap_ChannelMetadata {
uint32_t id;
pb_callback_t name;
......@@ -45,23 +35,33 @@ typedef struct _sadapmap_ReqChannelReading {
/* @@protoc_insertion_point(struct:sadapmap_ReqChannelReading) */
} sadapmap_ReqChannelReading;
typedef struct _sadapmap_ReqMultiChannelReading {
pb_size_t id_count;
uint32_t id[16];
/* @@protoc_insertion_point(struct:sadapmap_ReqMultiChannelReading) */
} sadapmap_ReqMultiChannelReading;
typedef struct _sadapmap_MultiChannelReading {
pb_size_t channels_count;
sadapmap_ChannelReading channels[16];
/* @@protoc_insertion_point(struct:sadapmap_MultiChannelReading) */
} sadapmap_MultiChannelReading;
/* Default values for struct fields */
/* Initializer values for message structs */
#define sadapmap_ChannelReading_init_default {0, 0}
#define sadapmap_MultiChannelReading_init_default {{{NULL}, NULL}}
#define sadapmap_MultiChannelReading_init_default {0, {sadapmap_ChannelReading_init_default, sadapmap_ChannelReading_init_default, sadapmap_ChannelReading_init_default, sadapmap_ChannelReading_init_default, sadapmap_ChannelReading_init_default, sadapmap_ChannelReading_init_default, sadapmap_ChannelReading_init_default, sadapmap_ChannelReading_init_default, sadapmap_ChannelReading_init_default, sadapmap_ChannelReading_init_default, sadapmap_ChannelReading_init_default, sadapmap_ChannelReading_init_default, sadapmap_ChannelReading_init_default, sadapmap_ChannelReading_init_default, sadapmap_ChannelReading_init_default, sadapmap_ChannelReading_init_default}}
#define sadapmap_ChannelMetadata_init_default {0, {{NULL}, NULL}, {{NULL}, NULL}, 0, 0}
#define sadapmap_ReqChannelReading_init_default {0}
#define sadapmap_ReqMultiChannelReading_init_default {{{NULL}, NULL}}
#define sadapmap_ReqMultiChannelReading_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}
#define sadapmap_ChannelReading_init_zero {0, 0}
#define sadapmap_MultiChannelReading_init_zero {{{NULL}, NULL}}
#define sadapmap_MultiChannelReading_init_zero {0, {sadapmap_ChannelReading_init_zero, sadapmap_ChannelReading_init_zero, sadapmap_ChannelReading_init_zero, sadapmap_ChannelReading_init_zero, sadapmap_ChannelReading_init_zero, sadapmap_ChannelReading_init_zero, sadapmap_ChannelReading_init_zero, sadapmap_ChannelReading_init_zero, sadapmap_ChannelReading_init_zero, sadapmap_ChannelReading_init_zero, sadapmap_ChannelReading_init_zero, sadapmap_ChannelReading_init_zero, sadapmap_ChannelReading_init_zero, sadapmap_ChannelReading_init_zero, sadapmap_ChannelReading_init_zero, sadapmap_ChannelReading_init_zero}}
#define sadapmap_ChannelMetadata_init_zero {0, {{NULL}, NULL}, {{NULL}, NULL}, 0, 0}
#define sadapmap_ReqChannelReading_init_zero {0}
#define sadapmap_ReqMultiChannelReading_init_zero {{{NULL}, NULL}}
#define sadapmap_ReqMultiChannelReading_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}
/* Field tags (for use in manual encoding/decoding) */
#define sadapmap_MultiChannelReading_channels_tag 1
#define sadapmap_ReqMultiChannelReading_id_tag 1
#define sadapmap_ChannelMetadata_id_tag 1
#define sadapmap_ChannelMetadata_name_tag 2
#define sadapmap_ChannelMetadata_unit_tag 3
......@@ -70,6 +70,8 @@ typedef struct _sadapmap_ReqChannelReading {
#define sadapmap_ChannelReading_id_tag 1
#define sadapmap_ChannelReading_value_tag 2
#define sadapmap_ReqChannelReading_id_tag 1
#define sadapmap_ReqMultiChannelReading_id_tag 1
#define sadapmap_MultiChannelReading_channels_tag 1
/* Struct field encoding specification for nanopb */
extern const pb_field_t sadapmap_ChannelReading_fields[3];
......@@ -80,10 +82,10 @@ extern const pb_field_t sadapmap_ReqMultiChannelReading_fields[2];
/* Maximum encoded size of messages (where known) */
#define sadapmap_ChannelReading_size 11
/* sadapmap_MultiChannelReading_size depends on runtime parameters */
#define sadapmap_MultiChannelReading_size 208
/* sadapmap_ChannelMetadata_size depends on runtime parameters */
#define sadapmap_ReqChannelReading_size 6
/* sadapmap_ReqMultiChannelReading_size depends on runtime parameters */
#define sadapmap_ReqMultiChannelReading_size 96
/* Message IDs (where set with "msgid" option) */
#ifdef PB_MSGID
......
#include <Arduino.h>
#include <pb.h>
#include <pb_common.h>
#include <pb_decode.h>
#include <pb_encode.h>
#include <sadapmap.pb.h>
void send_channel(uint8_t id, float value) {
uint8_t buffer[128];
sadapmap_ChannelReading reading = sadapmap_ChannelReading_init_default;
pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
reading.id = id;
reading.value = value;
uint8_t status = pb_encode(&stream, sadapmap_ChannelReading_fields, &reading);
uint8_t message_length = stream.bytes_written;
if(status)
Serial.write(buffer, message_length);
}
\ No newline at end of file
#include <Arduino.h>
#include <InstrumentInterface.hpp>
#include "ADS1115.h"
ADS1115 adc0(ADS1115_DEFAULT_ADDRESS);
void send_channel(uint8_t id, float value);
InstrumentInterface iface;
void multi_req_cb(bool status, sadapmap_ReqMultiChannelReading *req) {
if(!status)
return; // Pacote inválido
float readings[req->id_count] = {0};
for(uint8_t i = 0; i < req->id_count; i++) {
// Por enquanto só manda de um canal
adc0.setMultiplexer(ADS1115_MUX_P0_NG);
readings[i] = adc0.getMilliVolts(false);
}
iface.sendMultiChannel(req->id, readings, req->id_count);
}
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
Wire.begin();
Serial.begin(115200);
iface.init(Serial, &multi_req_cb);
Serial.println("Testing device connections...");
Serial.println(adc0.testConnection() ? "ADS1115 connection successful" : "ADS1115 connection failed");
//Serial.println("Testing device connections...");
//Serial.println(adc0.testConnection() ? "ADS1115 connection successful" : "ADS1115 connection failed");
adc0.initialize();
adc0.setMode(ADS1115_MODE_CONTINUOUS);
......@@ -20,12 +34,15 @@ void setup() {
}
void loop() {
/*
digitalWrite(LED_BUILTIN, LOW);
adc0.setMultiplexer(ADS1115_MUX_P0_NG);
adc0.triggerConversion();
send_channel(0, adc0.getMilliVolts(false));
sendChannel(0, adc0.getMilliVolts(false));
digitalWrite(LED_BUILTIN, HIGH);
delay(100);
*/
iface.pollMulti();
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment