Официальный сайт компании Arduino по адресу arduino.cc
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 * ? Пользуйтесь на здоровье.
Так вот же ТС пытался.
с_str() возращает const char* и отправив ее в структуру ой боюсь компилятор заругает.
По ссылке выше приведенной описан этот случай.
Так вот же ТС пытался.
Это не ТС пытался, а пример из библиотеки, который сопипасщен, но не понят. ТС же
И как я только не изгалялся, чтобы перевести String в Char или byte - ни в какую...
спасибо всем откликнувшимся!
пока получается так:
получается так:
Соответственно, на вторую ардуино ничего не передается.
Подскажите, как правильно присвоить 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]
речь про 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 (массив 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.
Не передашь ты стринг по простому.
Вывод: Hello Pp@ ? World
Этот мусор я предполагаю та самая служебная информация.
Простите, но Вы совсем неправы.
Во-первых здесь речь шла об ардуиновском классе String, а вовсе не об std::string
Ну, а дальше уже всё совсем на бред похоже.
А дальше передать структуру побайтно, но не совсем безопасный способ мне кажется с использованием String.
главный вопрос - нафига ? если есть char*
Мдя... В ардуине такой фокус не проходит. Выводит char и кусочек мусора.
А дальше передать структуру побайтно, но не совсем безопасный способ мне кажется с использованием String.
главный вопрос - нафига ? если есть char*
Модно, молодежно использовать String )))
Мдя... В ардуине такой фокус не проходит. Выводит char и кусочек мусора.
anarch, вы в своем коде перепутали String и std::string. это абсолютно разные вещи. Так что ваш результат не "в ардуине такое не проходит", а просто вообще ни о чем
а в Ардуино есть std::string?
Из коробки - нет. Если сами установите, то пожалуйста.
Из std вардуино искаропки есть только std::nullptr и нихрена больше