У меня очень странная проблема с библиотекой, которую я создаю. Библиотека будет использоваться для связи между модулями Arduino с использованием модулей XBee Series 1. Библиотека — это очень простая библиотека-оболочка для библиотеки Arduino XBee.
У меня есть одна функция, которая читает полученный пакет и отправляет его обратно. На данный момент он реализован в виде простой службы «эхо» — функция просто отображает полученные данные и отправляет их обратно по заданному адресу.
На данный момент у меня есть три версии этой функции, из которых одна не работает.
В этот момент я заметил странное поведение во 2-й версии функции. Я ничего не делаю с переданным аргументом — содержимое всех трех функций тот же самый. Во втором случае функция считывает неправильные значения из полученного пакета XBee. В 1-м и 3-м случае функция работает правильно.
Код:
ExampleLib.h
#ifndef ExampleLib_h
#define ExampleLib_h
#include "Arduino.h"#include <XBee.h>
#define ADDRESS_BROADCAST 0xffff
#define ADDRESS_PC 0x3333
typedef struct
{
int valA;
int valB;
int valC;
} valuesStruct;
class ExampleLib
{
public:
ExampleLib();
void setSerial(Stream &serial);
boolean tryReceivePacket();
void processPacket();
// THIS FUNCTION IS NOT WORKING!
void processPacket(valuesStruct valuesStructData);
void processPacket(valuesStruct* valuesStructData);
private:
XBee xbee;
Rx16Response rx16;
};
#endif
ExampleLib.cpp
Значение читается в строке byte* packetData = rx16.getData();
неправильно, когда мы запускаем processPacket(valuesStruct valuesStructData)
функция. В остальных случаях поведение правильное.
#include "Arduino.h"#include <XBee.h>
#include "ExampleLib.h"
ExampleLib::ExampleLib()
{
xbee = XBee();
rx16 = Rx16Response();
}
void ExampleLib::setSerial(Stream &serial)
{
xbee.setSerial(serial);
}
boolean ExampleLib::tryReceivePacket()
{
xbee.readPacket();
if (xbee.getResponse().isAvailable()) {
// got something
if (xbee.getResponse().getApiId() == RX_16_RESPONSE) {
// got a rx packet
xbee.getResponse().getRx16Response(rx16);
return true;
}
else {
return false;
}
}
else if (xbee.getResponse().isError()) {
//nss.print("Error reading packet. Error code: ");
//nss.println(xbee.getResponse().getErrorCode());
// or flash error led
return false;
}
return false;
}
void ExampleLib::processPacket()
{
byte* packetData = rx16.getData();
byte dataLength = rx16.getDataLength();
Serial.print("START L:");
Serial.println(dataLength);
for (int i = 0; i < dataLength; i++) {
Serial.print(packetData[i]);
Serial.print(" - ");
}
Serial.println("END");
//16-bit addressing: Enter address of remote XBee, typically the coordinator
Tx16Request tx = Tx16Request(ADDRESS_PC, packetData, sizeof(packetData));
xbee.send(tx);
}
void ExampleLib::processPacket(valuesStruct valuesStructData)
{
processPacket();
}
void ExampleLib::processPacket(valuesStruct* valuesStructData)
{
processPacket();
}
Эскиз Arduino
#include <XBee.h>
#include <ExampleLib.h>
ExampleLib exampleLibObj = ExampleLib();
void setup()
{
Serial.begin(9600);
exampleLibObj.setSerial(Serial);
}
void loop()
{
boolean isPacketReceived = exampleLibObj.tryReceivePacket();
if (isPacketReceived) {
// leave only one section, the rest should be commented
//Section 1: working
exampleLibObj.processPacket();
//Section 2: not working
// valuesStruct test;
// test.valA = 0;
// test.valB = 0;
// test.valC = 0;
// exampleLibObj.processPacket(test);
//Section 3: working
// valuesStruct* test;
// test->valA = 0;
// test->valB = 0;
// test->valC = 0;
// exampleLibObj.processPacket(test);
}
}
Я действительно озадачен, почему в этом случае функция работает по-другому. Ждем любых предложений по этому вопросу.
Спасибо,
Michal
Вы уверены, что не ваш раздел 3 вызывает проблемы? Потому что вы объявляете указатель на структуру, но не выделяете память для этой структуры.
Вы обычно пишете свой код так:
valuesStruct test;
test.valA = 0;
test.valB = 0;
test.valC = 0;
//Section 2: not working
exampleLibObj.processPacket(test);
//Section 3: working
exampleLibObj.processPacket(&test);
Но вы также обычно не передаете структуру функции — вы передаете указатель на эту структуру. Там действительно нет необходимости для вашего второго образца.