EasyTransfer + String
- Войдите на сайт для отправки комментариев
Ср, 25/09/2019 - 23:38
Коллеги, прошу помощи. Моих отрывчатых знаний не хватает, чтобы победить С++ ))
итак, есть 2 меги, соединенных через i2c с помощью либы easytransfer
образец либы:
Мастер:
#include <Wire.h>
#include <EasyTransferI2C.h>
//create object
EasyTransferI2C ET;
struct RECEIVE_DATA_STRUCTURE{
//put your variable definitions here for the data you want to receive
//THIS MUST BE EXACTLY THE SAME ON THE OTHER ARDUINO
int16_t blinks;
int16_t pause;
};
//give a name to the group of data
RECEIVE_DATA_STRUCTURE mydata;
//define slave i2c address
#define I2C_SLAVE_ADDRESS 9
void setup(){
Wire.begin(I2C_SLAVE_ADDRESS);
//start the library, pass in the data details and the name of the serial port. Can be Serial, Serial1, Serial2, etc.
ET.begin(details(mydata), &Wire);
//define handler function on receiving data
Wire.onReceive(receive);
pinMode(13, OUTPUT);
}
void loop() {
//check and see if a data packet has come in.
if(ET.receiveData()){
//this is how you access the variables. [name of the group].[variable name]
//since we have data, we will blink it out.
for(int i = mydata.blinks; i>0; i--){
digitalWrite(13, HIGH);
delay(mydata.pause * 100);
digitalWrite(13, LOW);
delay(mydata.pause * 100);
}
}
}
void receive(int numBytes) {}
Slave:
#include <Wire.h>
#include <EasyTransferI2C.h>
//create object
EasyTransferI2C ET;
struct SEND_DATA_STRUCTURE{
//put your variable definitions here for the data you want to send
//THIS MUST BE EXACTLY THE SAME ON THE OTHER ARDUINO
int16_t blinks;
int16_t pause;
};
//give a name to the group of data
SEND_DATA_STRUCTURE mydata;
//define slave i2c address
#define I2C_SLAVE_ADDRESS 9
void setup(){
Wire.begin();
//start the library, pass in the data details and the name of the serial port. Can be Serial, Serial1, Serial2, etc.
ET.begin(details(mydata), &Wire);
pinMode(13, OUTPUT);
randomSeed(analogRead(0));
}
void loop(){
//this is how you access the variables. [name of the group].[variable name]
mydata.blinks = random(5);
mydata.pause = random(5);
//send the data
ET.sendData(I2C_SLAVE_ADDRESS);
//Just for fun, we will blink it out too
for(int i = mydata.blinks; i>0; i--){
digitalWrite(13, HIGH);
delay(mydata.pause * 100);
digitalWrite(13, LOW);
delay(mydata.pause * 100);
}
delay(5000);
}
В примерах передаются данные int16_t.
А мне надо - string.
И как я только не изгалялся, чтобы перевести String в Char или byte - ни в какую...
#include <Wire.h>
#include <EasyTransferI2C.h>
//create object
EasyTransferI2C ET;
String sss="abcdef";
struct SEND_DATA_STRUCTURE{
//put your variable definitions here for the data you want to send
//THIS MUST BE EXACTLY THE SAME ON THE OTHER ARDUINO
int16_t blinks;
int16_t pause;
char ss[7];
};
//give a name to the group of data
SEND_DATA_STRUCTURE mydata;
//define slave i2c address
#define I2C_SLAVE_ADDRESS 9
void setup(){
Wire.begin();
Serial.begin(115200);
//start the library, pass in the data details and the name of the serial port. Can be Serial, Serial1, Serial2, etc.
ET.begin(details(mydata), &Wire);
pinMode(13, OUTPUT);
randomSeed(analogRead(0));
}
void loop(){
//this is how you access the variables. [name of the group].[variable name]
mydata.blinks = random(5);
mydata.pause = random(5);
for (byte i = 0; i <= sss.length()+1; i++) {
mydata.ss[i] = sss.substring(i,i+1).c_str();
Serial.print("char i=");Serial.println(mydata.ss[i]);
}
Serial.print("mydata.ss[6]=");Serial.println(mydata.ss);
Serial.print("mydata.pause=");Serial.println(mydata.pause);
//send the data
ET.sendData(I2C_SLAVE_ADDRESS);
//Just for fun, we will blink it out too
for(int i = mydata.blinks; i>0; i--){
digitalWrite(13, HIGH);
delay(mydata.pause * 100);
digitalWrite(13, LOW);
delay(mydata.pause * 100);
}
delay(500);
}
Может, подскажет кто?
явно что-то элементарное, чего я в упор не вижу...
зачем заводить String. чтобы потом мучаться и переводить ее в char? Что мешает сразу обьявить sss как
https://stackoverflow.com/questions/7352099/stdstring-to-char
И как я только не изгалялся, чтобы перевести String в Char или byte - ни в какую...
Боюсь даже представить, как Вы это делали. Только зачем её переводить, если у String есть готовый метод
который благополучно возвращает её буфер как char * ? Пользуйтесь на здоровье.
Боюсь даже представить, как Вы это делали. Только зачем её переводить, если у String есть готовый метод
который благополучно возвращает её буфер как char * ? Пользуйтесь на здоровье.
for (byte i = 0; i <= sss.length()+1; i++) { mydata.ss[i] = sss.substring(i,i+1).c_str(); Serial.print("char i=");Serial.println(mydata.ss[i]); }Так вот же ТС пытался.
с_str() возращает const char* и отправив ее в структуру ой боюсь компилятор заругает.
По ссылке выше приведенной описан этот случай.
Так вот же ТС пытался.
Это не ТС пытался, а пример из библиотеки, который сопипасщен, но не понят. ТС же
И как я только не изгалялся, чтобы перевести String в Char или byte - ни в какую...
спасибо всем откликнувшимся!
пока получается так:
char sss[7] = "abcdef"; struct SEND_DATA_STRUCTURE{ int16_t blinks; char ss; }; void loop(){ mydata.blinks = random(5); mydata.ss = sss; Serial.print("char i="); Serial.println(sss); Serial.print("mydata.ss[]=");Serial.println(mydata.ss); Serial.print("mydata.blinks=");Serial.println(mydata.blinks); ET.sendData(I2C_SLAVE_ADDRESS); }получается так:
Соответственно, на вторую ардуино ничего не передается.
Подскажите, как правильно присвоить mydata.ss = sss ?
вы экземпляр структуры mydata вообще не создаете? Метод detais() не вызываете? Или это вы просто скетч "сократили"?
выкладывайте все, чтобы не нужно было догадываться, что вы забыли по незнанию, а что "сократили", потому что думали не засорять форум
Подскажите, как правильно присвоить mydata.ss = sss ?
Никак. Они разных типов и разного размера.
Нельзя переменную размеров в 7 байтов впихнуть в переменную размером в 1 байт.
Подскажите, как правильно присвоить mydata.ss = sss ?
а ответы выше чуть внимательнее прочитать? в ветке всего 7 сообщений. считая ваши.
речь про strcpy(mydata.ss,sss.c_str()); ?
Евгений, тогда более общий вопрос - как String (массив char) передать по easytransfer?
ведь наверняка задача на 2 минуты... )
[quote=b707]
#include <Wire.h> #include <EasyTransferI2C.h> //create object EasyTransferI2C ET; char sss[7] = "abcdef"; struct SEND_DATA_STRUCTURE{ int16_t blinks; char ss; }; //give a name to the group of data SEND_DATA_STRUCTURE mydata; //define slave i2c address #define I2C_SLAVE_ADDRESS 9 void setup(){ Wire.begin(); Serial.begin(115200); //start the library, pass in the data details and the name of the serial port. Can be Serial, Serial1, Serial2, etc. ET.begin(details(mydata), &Wire); pinMode(13, OUTPUT); randomSeed(analogRead(0)); } void loop(){ //this is how you access the variables. [name of the group].[variable name] mydata.blinks = random(5); mydata.ss = sss; Serial.print("char i="); Serial.println(sss); Serial.print("mydata.ss[]=");Serial.println(mydata.ss); Serial.print("mydata.blinks=");Serial.println(mydata.blinks); ET.sendData(I2C_SLAVE_ADDRESS); delay(500); }речь про strcpy(mydata.ss,sss.c_str()); ?
да, я имел в виду это - но у вас не сработает, я просто не заметил всех ваших косяков. Читайте ответ Евгения
Евгений, тогда более общий вопрос - как String (массив char) передать по easytransfer?
ведь наверняка задача на 2 минуты... )
даже на одну. Превратить String в char* и передать.
А как передать непосредственно String - я не знаю. Может это и невозможно...
прям беда...
где-то видел (сейчас найти уже не могу), что этой либой можно переносить bytes, floats, int, но не стринг
а мне надо через i2c передать bytes, floats, int и string...
родная #wire вообще кроме байтов ничего не передает...
неужели единственный способ - конвертить string (char) в bytes, и их уже передавать?
А эти Ваши floats, int и что-то там ещё - не байты?
ну, в основе всего bytes...
ну, в основе всего bytes...
я вам больше скажу - char и byte - это грубо говоря одно и тоже
ПростоАлекс - судя по дискуссии, вы пока не готовы передавать string по wire. Вам нужно сесть и прочитать, что такое традиционные строки языка Си. Не эти навороченные ардуиновские String. а то что называется массивами символов
И тогда вы легко исправите ошибки в коде у вас все получится
я, конечно, ожидал готовый работающий код на блюдечке, но спасибо большое - пойду копать в сторону массивов ! )))
речь про strcpy(mydata.ss,sss.c_str()); ?
да, я имел в виду это - но у вас не сработает, я просто не заметил всех ваших косяков. Читайте ответ Евгения
А почему не сработает? Мне стало интересно.
я, конечно, ожидал готовый работающий код на блюдечке
А че так можно? :) А то мне код ядра для операционки нужен )))
да, я имел в виду это - но у вас не сработает, я просто не заметил всех ваших косяков. Читайте ответ Евгения
А почему не сработает? Мне стало интересно.
вы тоже читайте ответ Евгения :) в сообщении №8
ну так в первом примере ТС компилятор должен был ругаться типа нельзя присвоит const char* к char.
а во втором случае н в наглую пихает char[7] в char.
string myString = "Hello"; struct DATA{ char str[10]; }; DATA myData; strcpy(myData.str, myString.c_str());Что в такой записи вам не нравится. Или где то еще ТС напортачил и я не вижу?
string myString = "Hello"; struct DATA{ char str[10]; }; DATA myData; strcpy(myData.str, myString.c_str());Что в такой записи вам не нравится. Или где то еще ТС напортачил и я не вижу?
у ТС то было не так
Евгений, тогда более общий вопрос - как String (массив char) передать по easytransfer?
Я впервые слышу слово "easytransfer". Но если она умеет передавать 1 байт, то нужно просто сделать это столько раз, сколько символов в строке.
Я впервые слышу слово "easytransfer". Но если она умеет передавать 1 байт, то нужно просто сделать это столько раз, сколько символов в строке.
Евгений, эта библиотека определяет свой протокол с пакетами, у которых 6-8 байтов заголовка, а в конце "хвост" с контрольной суммой. Так что посылать данные побайтно тут будет не слишком эффективно :)
Вполне возможно. Я ж говорю, что впервые про неё слышу. Но, работать будет - стопудоф :-)))
Что вы тревожите мои колокольчики. Причем здесь, что библиотека передает.
В примере в нее засовывают структуру. А поэтому вообще не чего преобразовывать не нужно.
В структуре вместо char указать String и все будет кошерно.
В структуре вместо char указать String и все будет кошерно.
Точно? Вы у Раби консультировались?
В структуре вместо char указать String и все будет кошерно.
попробуйте себе ответить на очень простой вопрос - какой размер(в байтах) будет у этой структуры?
В описании либы сказано, что она понимает "все типы данных".
Но стринг не заработал, и в поисках правды в инете я нашел, что "все, кроме стринг".
Вообще говоря, мне эта либа не привязалась. Мне просто надо с минимальными для меня усилиями (сами видите, что из меня за программист) перекинуть через i2c данные
Не "все" и не "все кроме стринг", а только типы данных. имеющие заранее известный размер. String к ним не относится, так как экземпляры String умеют подстраивать свой размер в зависимости от строки. который в него поместили. А библиотека Easytransfer устроена так, что в ней нужно заранее задавать размер структуры.
Есть и другие классы с настраиваемым размером, String не единственный.
кстати, String-ам при инициализации можно указать фиксированный размер. В таком разе может и заработает. Но даже если заработает, вряд ли это будет эффективно, гораздо проще и очевиднее использовать для строк массив char
В структуре вместо char указать String и все будет кошерно.
попробуйте себе ответить на очень простой вопрос - какой размер(в байтах) будет у этой структуры?
String 6 байт. И?
String 6 байт.
Нет
ну по крайней мере sizeof(String) так думает
да, точно. Там наверно сама строка вообще не является элементом класса, а только ссылка на нее?
Тогда мои обьяснения выше, почему не работает - неверные, хотя вывод остается тот же :) - работать не будет. Причина не в том, что размер String заранее неизвестен, а в том что библиотека EasyTransfer в принципе не знает, как String хранит данные и потому не может получить к ним доступа
ну по крайней мере sizeof(String) так думает
теперь положи в String строчку "Lo que tienes que saber este viernes" и проверь размер снова
ну по крайней мере sizeof(String) так думает
теперь положи в String строчку "Lo que tienes que saber este viernes" и проверь размер снова
чудеса но те же 6 байт
2 байта указатель на сопсно строку и 4 байта служебной информации. Все правильно
Какой бы длины у тебя строка ни была, указатель на нее будет по прежнему 2 унылых байта.
А дальше передать структуру побайтно, но не совсем безопасный способ мне кажется с использованием String.
Не передашь ты стринг по простому.
#include <iostream> #include <cstring> using namespace std; std::string myString("Hello"); struct DATA{ char str[6]; string myStr; }; DATA myData; int main() { myData.myStr = "World"; strcpy(myData.str, myString.c_str()); for (int i=0;i<=(int)(sizeof(myData));i++) { cout << *(((char*)&myData)+i); } return 0; }Вывод: Hello Pp@ ? World
Этот мусор я предполагаю та самая служебная информация.
Простите, но Вы совсем неправы.
Во-первых здесь речь шла об ардуиновском классе String, а вовсе не об std::string
Ну, а дальше уже всё совсем на бред похоже.
А дальше передать структуру побайтно, но не совсем безопасный способ мне кажется с использованием String.
главный вопрос - нафига ? если есть char*
Мдя... В ардуине такой фокус не проходит. Выводит char и кусочек мусора.
А дальше передать структуру побайтно, но не совсем безопасный способ мне кажется с использованием String.
главный вопрос - нафига ? если есть char*
Модно, молодежно использовать String )))
Мдя... В ардуине такой фокус не проходит. Выводит char и кусочек мусора.
anarch, вы в своем коде перепутали String и std::string. это абсолютно разные вещи. Так что ваш результат не "в ардуине такое не проходит", а просто вообще ни о чем
а в Ардуино есть std::string?
Из коробки - нет. Если сами установите, то пожалуйста.
Из std вардуино искаропки есть только std::nullptr и нихрена больше