I2C Arduino - Arduino

Artyom9000
Offline
Зарегистрирован: 08.01.2016

Здравствуйте. Подключаю ардуино УНО к ардуино УНО посредством шины I2C.  Как на схеме:

Но без резисторов (без них мультиметр показывает напряжение ~4.7, должно хватать).  Скетч для первого ардуино (мастер): 

// Передатчик 

#include <Wire.h>  //подключаем библиотеку  
int ADDR = 15;  
byte val = 0;
void setup() 
{ 
  Serial.begin(9600);
   delay(5000);
  Wire.begin(); //включить i2c 
} 

void loop()// Главный цикл 
{ 
  delay(10000);
 Wire.beginTransmission(ADDR); // передача для устройства #15
   Wire.write(val);             // отправка байта val
   Wire.endTransmission();     // передача данных
}    

Для второго (слейв):

//Приёмник 

#include <Wire.h>  

int ADDR = 15;

void setup() 
{
    Serial.begin(9600);
     delay(5000);
Wire.begin(ADDR);
Wire.onReceive(Event);
}

void loop() {  
} 
void Event(int howMany){
 while(Wire.available()){
  char val = Wire.read();
 if(val == 0){
   delay(2000);
Serial.println("OK");
 } 
 } 
}

Выводом в последовательный порт выяснил, что не выполняется команда  Wire.endTransmission(); (т.е. не отправляется пакет данных). Соответственно передача данных с одной ардуины на другую не работает. Возможно нашел неправильный слейв адрес в даташите. Что я сделал не так?

P.S. На мастер адруино стоит Atmel mega328p-AU 1451 . На слейв ардуино- Atmel mega328p-AU 1533. 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Artyom9000 пишет:

но без резисторов 

Это как? Посмотрите на схему и скажите, что произойдёт, если кто-то из двух Ваших ардуин в процессе обмена подаст на 5 или 4 пин LOW? А она подаст - работать-то ей надо! Я могу ошибаться, но, кажется, раньше это называлось коротким замыканием.

Кстати, вот здесь предлагают вообще к питанию не притягивать - https://www.arduino.cc/en/Tutorial/MasterReader Посмотрите.

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Почему без внешних резисторов? Что мешает попробовать с внешними резисторами, это быстрее, чем писать вопрос.
http://easyelectronics.ru/interface-bus-iic-i2c.html

Artyom9000
Offline
Зарегистрирован: 08.01.2016

Резисторов сейчас под рукой нет, поэтому попробовал туториал, который Вы скинули. Все равно ничего не происходит, строку не выводит в сериал. В таком случае, вероятно, проблема в слейв адресе?

Artyom9000
Offline
Зарегистрирован: 08.01.2016

Проблема решена! Сделал I2C без 5V, как в туториале https://www.arduino.cc/en/Tutorial/MasterReader . И сменил слейв адрес. Правильный был не 15, а 30.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Artyom9000 пишет:

Сделал I2C без 5V, как в туториале https://www.arduino.cc/en/Tutorial/MasterReader . 

Ну, как-нибудь при встрече нальёте :)

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Жесть, передавать число в виде строки :) Просто - жесть :)

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

а вам говорят, что число надо передавать как число, тогда лишних преобразований не будет

facset
Offline
Зарегистрирован: 10.08.2016

DetSimen залейте стандартный код и передайте к примеру число 25031, и посмотрите что у вас примет слейв. Повторяю во второй раз: преобразую в текстовую переменную и обратно ДЛЯ РАЗДЕЛЕНИЯ переменной на отдельные числа, и уже эти ОТДЕЛЬНЫЕ числа передаю!!!

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

facset пишет:
залейте стандартный код

Что такое "стандартный код"? Каким стандартом он регламентируется?

facset пишет:
передайте к примеру число 25031, и посмотрите что у вас примет слейв.

У меня принимает ровно то, что я передаю. А у Вас? Уверен, что тоже! По-другому быть не может: что передано, то и принимается, контроллер сам ничего не выдумывает, он не настолько умный.

facset пишет:
Повторяю во второй раз: преобразую в текстовую переменную и обратно ДЛЯ РАЗДЕЛЕНИЯ переменной на отдельные числа, и уже эти ОТДЕЛЬНЫЕ числа передаю!!!

Так, а Вам объяснили, что это костыль и посоветовали делать правильно, чего капс-локом-то орать? Вы пришли за помощью, Вам её оказывают. А Вы орёте.

 

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

facset пишет:
DetSimen залейте стандартный код и передайте к примеру число 25031, и посмотрите что у вас примет слейв. Повторяю во второй раз: преобразую в текстовую переменную и обратно ДЛЯ РАЗДЕЛЕНИЯ переменной на отдельные числа, и уже эти ОТДЕЛЬНЫЕ числа передаю!!!

Это дичь. Число надо передавать числом, например - определились, что число у нас будет передаваться четырьмя байтами, чтобы влезть в максимальный диапазон - вот и передаём четыре байта, на другой стороне их принимаем - и всё. А передавать число "123456" в виде строки - это, как минимум, перерасход как по вычислительным ресурсам, так и по длине пакетов. Вот вам псевдокод для передачи числа:

unsigned long numToSend = 1234567;

byte* b = (byte*)&numToSend;

for(size_t i=0;i<sizeof(nupToSend);i++)
  client.write(*b++);

И где тут никому не нужные преобразования?

facset
Offline
Зарегистрирован: 10.08.2016

Так начинает что то маячить на горизонте, вроде показались первые 4 строчки кода и кой какое обьяснение к ним. Ну а я начну с начала:

1) уважаемые Форумчане прошу вас перечитать мой первый пост еще раз, и повнимательней.

2) и далее:

DetSimen пишет:

а вам говорят, что число надо передавать как число, тогда лишних преобразований не будет

а я как передаю? 

ЕвгенийП пишет:

У меня принимает ровно то, что я передаю. 

код в студию и желательно с пояснениями что к чему.

ну наверное, ну ваще, ну никто не заметил, поэтому выделил жирным. Рас Вам капс не нравится, кстати сори за капс:

facset пишет:

...... но как и в стандартной тут все на битах, что для меня темный лес, отправлять в разброд разные данные и получать то что нужно да еще при этом битами в шахматы играть, както хитро все это для меня. Пошевелив извилинами за 1 рабочую смену, методом "пальцем в небо" накарябал: .....

на мой взгляд ОООчень прожорливые функции, особенно на мастере, но с моим уровнем познаний, лучше не получается.

Теперь вопрос: может кто обьяснить как сделать подобное но на битовых операциях, желательно с подробными коментариями и разжовыванием что из чего получается, и почему получается так, а не иначе? подозреваю что на битовых операциях будет намного компактней.

а мне в ответ:

DetSimen пишет:

а вам говорят, что число надо передавать как число, тогда лишних преобразований не будет

как будто я сам не знаю и не спрашивал как??????

ЕвгенийП пишет:

Так, а Вам объяснили, что это костыль и посоветовали делать правильно, чего капс-локом-то орать? Вы пришли за помощью, Вам её оказывают. А Вы орёте.

 

угу супер обьяснили, супер помощь, супер совет и супер понятно как передать число - числом, прямо скажем пояснили/научили... :

DIYMan пишет:

Жесть, передавать число в виде строки :) Просто - жесть :)

DetSimen пишет:

а вам говорят, что число надо передавать как число, тогда лишних преобразований не будет

следущее:

DIYMan пишет:

Это дичь. Число надо передавать числом. ........ А передавать число "123456" в виде строки - это, как минимум, перерасход как по вычислительным ресурсам, так и по длине пакетов.

Я и не говорил что надо строкой, DIYMan большая просьба к Вам тыкните пожалуйста меня мордой в мой код, в то место где я, передаю число строкой, как Вы изволите утверждать.

DIYMan пишет:

И где тут никому не нужные преобразования?

а никто и не говорил что ненужные преобразования есть в Вашем коде, все утверждали что они есть в моем коде и я с этим согласен, но при этом я дважды пояснил для чего они, хотя походу никто этого не заметил, все заметили что они есть, и никто до поста №12 (DIYMan спс за кусок кода и хоть какието пояснения) в данной теме, никто не потрудился привести пример рабочего кода и обьяснений к нему, кстати  не могли бы пояснить (что вобщем то и просил в моем первом посте) пару вопросов:

1. (byte*)&numToSend; знак & нафига?

2. for(size_t i=0;i<sizeof(nupToSend);i++) это откуда и куда и зачем? size_t

3. какой билиотекой пользуемся? client.write(*b++);

4. и про звездочки что стоят в 3 и 6й строчке вашего кода

кстати откуда дровишки, ссылочкой не поделитесь?

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Строка 39-40 вашего скетча - там вы преобразуете КАЖДЫЙ символ уже ТЕКСТОВОГО представления числа - в число, вдвойне дичь. По остальным вопросам ко мне - перенаправлю вас на учебник по С++, лишь по пункту 3 замечу - я писал, что это ПСЕВДОкод. Что это такое - гуглить, не лениться.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

facset пишет:

код в студию и желательно с пояснениями что к чему.

Добавьте ещё "время пошло!". Я Вам что-то задолжал?

Какой там код, просто берёте байт и тупо его пересылаете. Если у Вас число типа int - пересылаете два байта, если long - четыре. Там и кода-то никакого нет - всё гораздо проще, чем Вы написали.

b707
Offline
Зарегистрирован: 26.05.2017

facset пишет:

Так начинает что то маячить на горизонте, вроде показались первые 4 строчки кода и кой какое обьяснение к ним. Ну а я начну с начала:

фигней не майтесь - в первом сообщении темы готовый код. Если вы "не понимаете биты" - это ваши проблемы и они тут никому не интересны. Учитесь.

Вы спрашивали "В каком месте я передаю число как строку?" - в коде мастера строка 35 и последующие.

 

facset
Offline
Зарегистрирован: 10.08.2016

b707 пишет:

фигней не майтесь - в первом сообщении темы готовый код.

в этом коде стартер темы пытается отправить число которое заранее известно: 0 типа byte и то возникли проблемы, хотя пример из библиотеки Wire прекрасно с этим справляется, мне же нужно отправлять переменную которая заранее не известна и расчитывается самим мк в процессе работы и может быть типа int  или long.

 

b707 пишет:

Учитесь.

Вы спрашивали "В каком месте я передаю число как строку?" - в коде мастера строка 35 и последующие.

я бы и рад поучиться но никто учить не хочет, все только указывают

может прозвучит грубо но накипело заранее прошу прощения: по внимательней прочитайте мой код и коменты в нем, предыдущие посты в которых я разжувал и не раз, что и для чего я делаю, не помогает так попробуй настроить монитор, не помогает опять, обратитесь к окулисту. еще раз извеняюсь но пукан подгорает.

facset
Offline
Зарегистрирован: 10.08.2016

DIYMan пишет:

Строка 39-40 вашего скетча - там вы преобразуете КАЖДЫЙ символ уже ТЕКСТОВОГО представления числа - в число, вдвойне дичь. По остальным вопросам ко мне - перенаправлю вас на учебник по С++, лишь по пункту 3 замечу - я писал, что это ПСЕВДОкод. Что это такое - гуглить, не лениться.

правильно заметили но не правильно поняли, беру переменную int  или long загоняю в текстовую переменную, из текстовой переменной беру цифру под порядковым номером i (с помощью цикла for) и передаю во временную текстовую переменную (Ваше ТЕКСТОВОГО представления числа), чтобы из временной переменой переделать в числовой массив типа byte, тем самым я делю\дроблю\разделяю (нужное подчеркнуть) переменную типа int или long на отдельные цыфры - байты и уже их отправляю, чтобы собрать на той стороне, так понятно? если же отправлять Ваше ТЕКСТОВОГО представления числа то на той стороне получаем всякую фигню но не то что отправляли.

за учебник конечно спасибо но не вижу смысла в том чтобы изучать ВЕСЬ материал по програмированию на языке С, (темболее что отличия от того что используется в ардуинке свеже имеются, ардуиновский сльно упрощен потому ее и юзаю) для того чтобы написать вроде бы не сильно то сложный код, в чем меня все вокруг уверяют, но оказать конкретную помощь по конкретному вопросу не в состоянии как видно

ЕвгенийП пишет:

Добавьте ещё "время пошло!". Я Вам что-то задолжал?

нет не должны, но как я вижу ваш код секрет за семью печатями и нидай боже кто увидит (по Вашим и многим другим коментам создается такое впечатление).

как я считал форум предназначен для помощи, общения и обьяснения, но как видно большинству из его участников легче всего помочь остальным так: идите туда низнаю куда принисите то низнаю что, и гдето там сделайте то незнаю что, и обязательно вернитесь к назначенному времени!

типа я спрашивал прописные истины, и все о них знают с пеленок, может и так но:

facset пишет:

Теперь вопрос: может кто обьяснить как сделать подобное но на битовых операциях, желательно с подробными коментариями и разжовыванием что из чего получается, и почему получается так, а не иначе? подозреваю что на битовых операциях будет намного компактней.

я привел пример того как у меня это получилось и задал вопрос, как???? это сделать на битах, и обьяснить.  

ЕвгенийП пишет:

Какой там код, просто берёте байт и тупо его пересылаете. 

беру код из примера от библиотеки Wire, и тупо отправляю 300 и получаю 255 и далее от 0 и до 255, 

ЕвгенийП пишет:

Если у Вас число типа int - пересылаете два байта, если long - четыре. Там и кода-то никакого нет - всё гораздо проще, чем Вы написали.

оббана щелочка в двери за семью печатями, просочилось информация, а в первом своем посте могли это написать вместо того что бы троллить? вы это написали и от вас что то убыло? вы что то из за этого потеряли? могли же и сразу написать а не тупо тыкать в передачу числом, тем более что моя функция и передает числа но по отдельности, да писал же что в битах\байтах не разбираюсь.

теперь вопрос как передать 2 байта как переслать 4 байта, да понимаючто это можно найти в учебнике по программировнию, (читал както но нихрена не понял, пример: вы возьмите учебник по астрофизике или как ее там, почитайте пару часиков и что все сразу поймете? или еще учебник по молекулярной биотехнологии и т.д.) как советовал DIYMan, но МК хобби и сильно углубляться в програмирование нет ни времени ни особого пока желания, смог же я без учебника по С## функцию по передаче по I2C шине написать, да громоздко, да долго для мк выполняется, но работает же!! потому и просил помощи, а не очередного совета идти учиться в институт, типа там расскажут и покажут, а тут взрослые дяди сидят которым все и так известно.

а в остальном все круто спасибо, круто помогли, привели пример (ты число передай числом а не строкой, не буду ругаться но очень почемуто хочется), рассказали, обьяснили, научили мля, только не вижу смысла в абстрактных ответах на конкретные вопросы и просьбы. 

ладно все вопросы снимаю ибо вижу что на этом форуме конкретно никто ничего не знает и не понимает сам (по Вашим ответам складывается такое впечатление) ибо все всё знают на уровне инстинктов ибо впитали с молоком матери в младенчестве. (шото меня понесло, как говорят в WOT пукан горит))) пошол учить учебник по програмированию думаю за полгодика осилю что нибуть, вместо помощи и решения задачи в течении суток, других. БОЛЬШАЯ ВСЕМ БЛАГОДАРНОСТЬ. ведь такая помощь в корне убивает желание что то делать с мк / изучать языки програмирования

b707
Offline
Зарегистрирован: 26.05.2017

facset пишет:

может прозвучит грубо но накипело заранее прошу прощения: по внимательней прочитайте мой код и коменты в нем, предыдущие посты в которых я разжувал и не раз, что и для чего я делаю

может прозвучит грубо, но и я и другие уже сотню раз прочитали твой код и отлично видим, что и для чего ты делаешь. Делаешь ты - за ухом чешешь левой пяткой, а из-за чего - из-за своей тупости и лени.

Давно бы уже пошел в гугль и прочитал, как поделить инт на байты. И как на другой стороне собрать обратно.

b707
Offline
Зарегистрирован: 26.05.2017

facset пишет:

БОЛЬШАЯ ВСЕМ БЛАГОДАРНОСТЬ. ведь такая помощь в корне убивает желание что то делать с мк / изучать языки програмирования

Не надо врать, желания ихзучать у тебя нет и не было. И ты сам не раз пишешь об этом.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Млять, ещё один упоротый - ему про Фому, он про Ерёму. Нет чтобы нормально начать учиться, раз уж взез в программирование, нет - вы посмотрите на мой говнокод, мне надо только так, и всё тут! Писец какой-то.

Болезный, для того, чтобы принимающая и передающая сторона понимали, какие данные какого типа передаются/принимаются - они должны об этом условиться заранее, т.е. сформировать письмо, где будет написано, какое в нём содержимое. А делать анальный секс с числом, склоняя его к тройному проникновению в особо жёсткой форме - это дичь.

Псевдокод работы пакетной передачи/приёма:

typedef enum 
{
	packetByte,
	packetInt,
	...
	
} packetType;

typedef struct
{
	byte header1;
	byte header2;
	byte header3;
	packetType type;
	
} packetHead;


void receivePacket(Stream& s)
{
	if(s.available() < sizeof(packetHead))
		return;
	
	packetHead head;
	s.read(&head,sizeof(head));
	
	if(!(head.header1 == 1 && head.header2 == 2 && head.header3 == 3)) // плохой заголовок, битый пакет
                  return;
		
	
	switch(head.type)
	{
		case packetByte:
			while(!s.available());
			
			byte b = s.read(); // прочитали байт
		break;
		
		case packetInt:
			while(s.available()<sizeof(int));
			int i;
			byte* b = (byte*)&i;
			*b++ = s.read();
			*b = s.read();
			// прочитали число двухбайтовое
		break;
		
		....
	}
}

Что тут непонятного? Если чуть более, чем всё - учить основы языков С и С++.

 

b707
Offline
Зарегистрирован: 26.05.2017

DIYMan, в строке 43 не ошибка? У тебя же переменная типа int. значит инкремент указателя даст сдвиг на два байта, а не один. Думаю, указатель на i перед инкрементом надо к типу byte* приводить.

А. увидел, это просто описка - там в 42 строке у тебя даже указатель приготовлен, просто ты забыл заменить. В строках 43 и 44 вместо *i должно быть b

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

b707 пишет:

DIYMan, в строке 43 не ошибка? У тебя же переменная типа int. значит инкремент указателя даст сдвиг на два байта, а не один. Думаю, указатель на i перед инкрементом надо к типу byte* приводить.

А. увидел, это просто описка - там в 42 строке у тебя даже указатель приготовлен, просто ты забыл заменить. В строках 43 и 44 вместо *i должно быть b

Да, описАлся, щас поправлю, спс. Я ж такие примеры сразу в Notepad++ пишу, а он, как известно, компилировать не обучен :) Поэтому всегда и акцентирую внимание, что это псевдокод ;)

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

facset пишет:
из текстовой переменной беру цифру под порядковым номером i (с помощью цикла for) и передаю во временную текстовую переменную (Ваше ТЕКСТОВОГО представления числа), чтобы из временной переменой переделать в числовой массив типа byte, тем самым я делю\дроблю\разделяю (нужное подчеркнуть) переменную типа int или long на отдельные цыфры - байты и уже их отправляю

Ну, если Вы умеете отправлять байты, то какой, простите мой французский, хер мешает Вам просто отправить два байта из которых состоит число типа int? Просто отправить сначала один, потом второй? Безо всяких строк, преобразований и прочих мудростей?

facset пишет:

как я считал форум предназначен для помощи, общения и обьяснения,

Нет - только для общения. Помощь и объяснение - это в школе или на платных курсах. А чтобы с Вами общались (и заодно, в процессе общения, объясняли и помогали), надо не хамить, а сделать так, чтобы с Вами было интересно общаться.

Вам здесь реально пытаются помочь, объясняют что делать. Объясняют - так делайте же! Хотя бы пробуйте, выкладывайте пробы и спрашивайте что не так, а не хамите.

Есди же Вы не желаете пробовать самостоятельно, а желаете всенепременно 

facset пишет:

код в студию и желательно с пояснениями что к чему.

то топайте в профильный раздел. Там за бабки Вам выложат в студию столько кода, сколько оплатите. Вы не туда попали.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Это не "дичь", это уже повсеместно. Результат "егэшного" образования той самой "болонской школы фурсенков", от которой сами французы уже отказались, ибо доказали себе что за 10 лет качество обучения значительно упало. Им хватило всего 10 лет .. интересно, сколько ещё будут тупить у нас?