N

Вопрос мастерам или ардуино Шредингера.

9 сообщений в этой теме

Есть задача, опрашивать несколько ардуино по I2C с целью вывести полученное на дисплей.
Рабочий код прикладываю, подсоединял по мануалу пробовал подтягивать SCL и SDA резисторами на 1,5кОм.
Вопрос в следующем.
Почему то поле некоторого времени слейв перестает определятся.
Скан видит любую перефирию I2C кроме ардуинки

Код (C++):

Код мастера

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x26,16,2);
#include <Wire.h>
char co = 0 ;

void setup() 
  {
 
  Wire.begin();        // join i2c bus (address optional for master)
  lcd.init();
  lcd.backlight();
  Serial.begin(9600);  
  }
 
void loop() 
  {
     
     Wire.requestFrom(0x10, 4,true);
     lcd.setCursor(0,0);
     while (Wire.available()) 
        { 
          co = Wire.read(); 
          Serial.print(co);         
          lcd.print(co);   
        }
        delay(200);
    
   
     Serial.print(" ");
     
     Wire.requestFrom(0x10, 7,true);    // request 6 bytes from slave device #8
     lcd.setCursor(4,0);
     while (Wire.available()) 
        { 
          co = Wire.read(); 
          Serial.print(co);         
          lcd.print(co);   
        }
   
  Serial.print("\n");
  delay(200);
  lcd.clear();
}



Код (C++):

Код слейва


01 #include <Wire.h>
02
03 byte stat = true;
04
05 char c[4] = {'N','O',' ',' '};
06 float x = 322.345;
07 void setup() {
08  Wire.begin(0x10);
09  pinMode(13, OUTPUT);
10  Serial.begin(9600);
11  Wire.onRequest(requestEvent);
12 }
13
14 void loop() {
15  digitalWrite(13, LOW);
16  delay(100);
17
18 }
19
20 void requestEvent() {
21  if (stat == true)
22  {
23
24  Wire.write(c,sizeof c);
25  stat = false;
26  }else
27  {
28  char outstr[7];
29  dtostrf(x,7, 3, outstr);
30  Wire.write(outstr,sizeof outstr);
31  stat = true;
32  }
33  digitalWrite(13, HIGH);
34
35
36
37
38 }

 

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Перепиши код в AVR Studio и все будет работать

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
4 минуты назад, BARS_ сказал:

Перепиши код в AVR Studio и все будет работать

Буду пробовать, вы думаете это из за кривого компилятора?

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Только что, Nikita kozlovtcev сказал:

кривого компилятора

Скорее из-за кривого кода

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
1 минуту назад, BARS_ сказал:

Скорее из-за кривого кода

а ну тогда как AVR студия поможет?))

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Только что, Nikita kozlovtcev сказал:

как AVR студия поможет?

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

С какой целью выбран I2C?

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
2 минуты назад, BARS_ сказал:

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

Так то на асемблере запускал.

А на си не писал раньше, из за этого и проблемы.

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Только что, Nikita kozlovtcev сказал:

Так то на асемблере запускал

Так и напиши на асме, там же код короткий совсем. Почему именно I2C?

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Первое что бросилось в слейве, зачем ты в скорости обмена данных прописал адрес слейва? Wire.begin(0x10); Адресс слейва можно считать кодом сканера, и его можно менять перемычкамит на плате слейва(если есть, смотря что за устройство). Данные в ардуинно иде через библиотеку Wire, отправлял через другие три функции, и к тому же ты насадил на I2C и дисплей и передаешь данные куда-то, возможно в этом конфликт, так как нужно смотреть что в библиотеке на 1602 прописано, там ведь тоже все время идет обмен данными, в таком случае дисплей на I2Cоставляй, а прием передачу данных делай по ЮАРту.

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Ваша публикация должна быть проверена модератором

1
Вы не авторизованы. Если у вас есть аккаунт, пожалуйста, войдите.
Ответить в тему...

×   Вы вставили отформатированное содержимое.   Восстановить форматирование

  Разрешено не более 75 смайлов.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был востановлен.   Очистить редактор

Загрузка...

  • Похожие публикации

    • Автор: ximik_se
      Всем привет.

      Решил сделать небольшую домашнюю метеостанцию.

      Есть приемник с экраном, куда выводится инфа (построено на ATMEGA 328P) и есть передатчик, который посылает инфу по возудху (построено на ATtiny85).

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

      При этом время между измерениями не меньше 20 сек.

      В общем заказал я себе с Китаюшки более точные датчики - 

      CJMCU-1080 HDC1080
      Вещица прекрасная, но общается по I2C.

      А библиотеку рабочую под нее я смог найти только одну "ClosedCube_HDC1080.h" и никаких модификаций под ATtiny я найти не смог.

      Для ее работы соответственно нужен Wire.h

      В общем решил я его поковырять самостоятельно, хоть и не прогер. Забрался во внутренности ClosedCube_HDC1080.cpp и везде заменил Wire на TinyWireM (некий аналог Wire для ATtiny).

      И у меня даже получилось считывать валжность, но вот вместо температуры приходит гадость. Ибо при компиляции Arduino IDE ругалась на строку (я ее ниже в коде закомментировал)
      uint8_t buf[4]; for (int i = 1; i < (seconds*66); i++) { TinyWireM.beginTransmission(_address); TinyWireM.write(0x00); TinyWireM.endTransmission(); delay(20); TinyWireM.requestFrom(_address, (uint8_t)4); // TinyWireM.readBytes(buf, (size_t)4); } Ошибку пишет следующую:

      \ClosedCube_HDC1080.cpp: In member function 'void ClosedCube_HDC1080::heatUp(uint8_t)':

      \ClosedCube_HDC1080.cpp:81:13: error: 'class USI_TWI' has no member named 'readBytes'

      TinyWireM.readBytes(buf, (size_t)4);
      Может есть ребята более понимающие в коде и сумеющие победить эту проблему, чтобы и температуру этот датчик смог передавать через ATtiny85.

      Вот полный текст файла ClosedCube_HDC1080.cpp (уже замененный ну и строчка закоментирована):
      #include <TinyWireM.h> #include "ClosedCube_HDC1080.h" ClosedCube_HDC1080::ClosedCube_HDC1080() { } void ClosedCube_HDC1080::begin(uint8_t address) { _address = address; TinyWireM.begin(); // Heater off, 14 bit Temperature and Humidity Measurement Resolution TinyWireM.beginTransmission(_address); TinyWireM.write(CONFIGURATION); TinyWireM.write(0x0); TinyWireM.write(0x0); TinyWireM.endTransmission(); } HDC1080_Registers ClosedCube_HDC1080::readRegister() { HDC1080_Registers reg; reg.rawData = (readData(CONFIGURATION) >> 8); return reg; } void ClosedCube_HDC1080::writeRegister(HDC1080_Registers reg) { TinyWireM.beginTransmission(_address); TinyWireM.write(CONFIGURATION); TinyWireM.write(reg.rawData); TinyWireM.write(0x00); TinyWireM.endTransmission(); delay(10); } void ClosedCube_HDC1080::heatUp(uint8_t seconds) { HDC1080_Registers reg = readRegister(); reg.Heater = 1; reg.ModeOfAcquisition = 1; writeRegister(reg); uint8_t buf[4]; for (int i = 1; i < (seconds*66); i++) { TinyWireM.beginTransmission(_address); TinyWireM.write(0x00); TinyWireM.endTransmission(); delay(20); TinyWireM.requestFrom(_address, (uint8_t)4); // TinyWireM.readBytes(buf, (size_t)4); } reg.Heater = 0; reg.ModeOfAcquisition = 0; writeRegister(reg); } float ClosedCube_HDC1080::readT() { return readTemperature(); } float ClosedCube_HDC1080::readTemperature() { uint16_t rawT = readData(TEMPERATURE); return (rawT / pow(2, 16)) * 165 - 40; } float ClosedCube_HDC1080::readH() { return readHumidity(); } float ClosedCube_HDC1080::readHumidity() { uint16_t rawH = readData(HUMIDITY); return (rawH / pow(2, 16)) * 100; } uint16_t ClosedCube_HDC1080::readManufacturerId() { return readData(MANUFACTURER_ID); } uint16_t ClosedCube_HDC1080::readDeviceId() { return readData(DEVICE_ID); } uint16_t ClosedCube_HDC1080::readData(uint8_t pointer) { TinyWireM.beginTransmission(_address); TinyWireM.write(pointer); TinyWireM.endTransmission(); delay(9); TinyWireM.requestFrom(_address, (uint8_t)2); byte msb = TinyWireM.read(); byte lsb = TinyWireM.read(); return msb << 8 | lsb; }  
    • Автор: Wyfinger
      Всем привет.
      Существуют ли готовые модули для измерения мгновенных значений тока и напряжения (ток до 100 А, напряжение до 250 вольт)?
      Т.е. измерять нужно с частотой 1000-5000 герц, точность 14-16 бит, связь по SPI лучше всего.
      Вообще нужно хотя-бы 4 канала по току и 4 по напряжению. Но лучше, чтобы можно было на одну шину ставить несколько модулей, расширяя количество каналов.
      Обрабатывать данные собираюсь на STM32F104 (хотя с ним никогда не работал) или Arduino Due, но это не важно.
      Понятно что можно взять АЦП и шунт или делитель напряжения, но хотелось бы готовый модуль и уже с оптической развязкой.
      Подскажите если кто сталкивался.
       
    • Автор: StasRadeon
      Люди добрые, помогите кто может!
      потому что имею HD44780 + PCF8547, хотел сделать i2c library.
      скажите пожалуйста где делаю неправильно.
      прикрепляю PrintScreen от Proteus ISIS

      #include <htc.h> #define _XTAL_FREQ 4000000 //******************************************************** #pragma config FOSC = INTRC_CLKOUT// Oscillator Selection bits (INTOSC oscillator: CLKOUT function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register) #pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled) #pragma config MCLRE = OFF // RE3/MCLR pin function select bit (RE3/MCLR pin function is digital input, MCLR internally tied to VDD) #pragma config CP = OFF // Code Protection bit (Program memory code protection is disabled) #pragma config CPD = OFF // Data Code Protection bit (Data memory code protection is disabled) #pragma config BOREN = ON // Brown Out Reset Selection bits (BOR enabled) #pragma config IESO = OFF // Internal External Switchover bit (Internal/External Switchover mode is disabled) #pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled) #pragma config LVP = ON // Low Voltage Programming Enable bit (RB3/PGM pin has PGM function, low voltage programming enabled) // CONFIG2 #pragma config BOR4V = BOR40V // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V) #pragma config WRT = OFF // Flash Program Memory Self Write Enable bits (Write protection off) //******************************************************** #define LCD_DISPLAYMODE 0x08 #define pic_frq 16000 // controller frequenc #define i2c_frq 400 // #define gen_frq (((pic_frq / i2c_frq) / 4) - 1) void i2cByteWrite(char, char, char); void i2cTxData(char); void LCD_dat(char); void LCD_cmd(char); void LCD_clr(void); void LCD_int(void); void LCD_str(char *); void LCD_ROMstr(const char *); void LCD_posyx(char,char); void LCD_hex(char); void i2c_init(); //////////// Main ////////////////////////////////// void main(void){ char msgStart[] ="LCD Work"; unsigned char num = 0; OSCCON = 0b00110000; //4Mhz TRISC = 0b11111111; PORTC = 0x00; i2c_init(); LCD_int(); // ------------------------------------------------------ LCD_str(msgStart); // LCD_dat(' '); LCD_dat('!'); // ------------------------------------------------------ LCD_posyx(1,0); // LCD_ROMstr("12345"); while(1){ LCD_posyx(0,14); // LCD_hex(num++); // __delay_ms(1000); // 1000msec } } void i2c_init() { TRISC3 = 1; TRISC4 = 1; SSPSTAT = 0b10000000; // Slew rate disabled SSPCON = 0b00101000; //(0x28) SSPEN = 1, I2C Master mode, clock = FOSC/(4*(SSPADD+1)) SSPCON2 = 0b00000000; // SSPADD = gen_frq; } // ----------------------------------------------------------- void i2cByteWrite(char addr, char cont, char data){ SEN = 1; // Start condition while(SEN); // if (Start condition) i2cTxData(addr); // i2cTxData(cont); // i2cTxData(data); // SSPIF = 0; // PEN = 1; // Stop condition while(PEN); // Stop condition } void i2cTxData(char data){ SSPIF = 0; // SSPBUF = data; // while(!SSPIF); // } // ----------------------------------------------------------- void LCD_dat(char chr){ i2cByteWrite(0xA0, 0x80, chr); __delay_us(60); // 60 usec } // ----------------------------------------------------------- void LCD_cmd(char cmd){ i2cByteWrite(0xA0, 0x00, cmd); if(cmd & 0xFC) // __delay_us(60); // 60usec else __delay_ms(3); // 3msec } // ----------------------------------------------------------- void LCD_clr(void){ LCD_cmd(0x01); //Clear Lcd } void LCD_posyx(char ypos, char xpos){ unsigned char pcode; switch(ypos & 0x03){ // case 0: pcode=0x80;break; // 1line case 1: pcode=0xC0;break; // 2line case 2: pcode=0x94;break; // 3line case 3: pcode=0xD4;break; // 4line } LCD_cmd(pcode += xpos); // } // ----------------------------------------------------------- void LCD_str(char *str){ while(*str) // LCD_dat(*str++); // } // ----------------------------------------------------------- void LCD_ROMstr(const char *str){ while(*str) // LCD_dat(*str++); // } // ----------------------------------------------------------- void LCD_hex(char c){ const char hexch[] ="aaaa"; LCD_dat(hexch[c >> 4]); // LCD_dat(hexch[c & 0xF]); // } // ----------------------------------------------------------- void LCD_int(void){ __delay_ms(100); // LCD_cmd(0x28); // 4 bit mode LCD_cmd(LCD_DISPLAYMODE | 0x00); // Display on Cursor=0 Blink=0 LCD_cmd(0x06); // Entry Inc/Dec=1 Shift=0 LCD_cmd(0x01); // Clear Display }

    • Автор: Ittido
      Добрый день. Пытаюсь сделать конвеер для аппаратного TWI модуля ATMega8. Контроллер в режиме мастера периодически работает с 4 разными устройствами на шине. LCD1602 висит также на шине I2C. Инициализация проходит информация на LCD выводится. Далее идёт процесс опроса времени с DS3231. Время передаётся но в конце при передаче СТОП на линию І2С. СТОП не проходит. Логический анализатор показывает на линии SCL - 1, SDA - 0. В регистре статуса F8. Ожидание ни к чему не приводит. Продолжение кода тоже. Как с этим бороться может кто сталкивался.
    • Автор: POlSS0N
      Хочу сделать, чтобы контроллер опознавал самостоятельно факт подключения к линии i2c внешних устройств.
      Предполагаю периодически рассылать запросы на запись по каждому адресу и записывать, пришло ли подтверждение или нет, после чего сразу прерывать работу стоп-битом.
      Возникает вопрос - как поведет себя другой контроллер, если он подтвердит готовность принять некие данные а в результате вместо тактов он получит стоп-бит?
      Может, в стандарте i2c есть общепринятый метод опроса адресов?
  • Сообщения

    • ему "эти" помогали
    • Кто ни будь пробовал для плавного пуска вместо реле что то типа MOC3063 + mac15-10 ?
    • Большое спасибо за ответы дорогие форумчане. Но боюсь на осваивание темы компараторов и транзисторов у меня уйдет куча времени. А его у меня последнее время крайний дефицит. Я прошу вас набросать готовую схемку хоть на транзисторах, хоть на компараторе, большой разницы нет.  Тема почти автомобильная, точнее зажигание двухтактного двигателя скутера 20 лет назад снятого с производства. Оригинальных запчастей на него нет и не будет, приходится прикручивать то что  есть. Беда в том что на этом скутере итальянцы поэксперементировали один раз - получилось достаточно компактно но не надежно и на других моделях такую схему больше нигде не использовали. Сопротивление обмотки датчика положения с которого идет импульс 600 ом, Максимальное число оборотов 14000 об/мин. На оборотах выше 3000 отрицательные импульсы начинают выпрыгивать в плюсовую сторону до 0.5v, соответственно  порог срабатывания надо подобрать 0.7- 0.8v Готов отблагодарить материально за практическую помощь.
    • не думаю, что у кого-то хватит "УМА" на ЭТО Он и даром как изделие никому не нужен!
    • Нарисовал схемы кодера, декодера и регуля. Кодер согласно ссылке Жмяк  ,Согласно усовершенствованию автора добавлены подстроечники, их попробую поменьше купить, а то эти огромные. Три пина слева- для передатчика, воткну пока самый дешевый и наверное самый бородатый китайские передатчик и приемник (комплект на 315Мгц) Декодер по ссылке Жмяк с некоторыми доработками, питание 5В, резистор светодиода 330 Ом и по все выходам поставил токоограничивающие по 300 Ом, вычитал что максимальный ток порта 20мА, с резисторами должен быть не более 16,6мА, вроде запас есть. 4 отдельных пина- для приемника Регулятор по ссылке тык . Плечи моста не симметричные, ибо в одну сторону двигаться будет всяко больше модель, чем в другую, значит на одном плече сэкономим. Мосфеты P и N канальные, в Dpack корпусе(или ТО252, вроде так). Вместо управляющего P-мосфетами полевика воткнул биполярник мелкий(sot23), должно хватить с током коллектора макс 0,15А. Расположение деталей с двух сторон будет, на мосфеты если что удобно будет радиатор приспособить, дорожки может потом еще проводом утолщу, по калькуляторам ширина маловата (раза в два). Резистор на 1кОм не стал оставлять как в исходной схеме, раз на выходе приемника уже стоят токоограничивающие, то счел здесь ненужным еще один (может не прав). И конденсатор по питанию электролит на 100 мкФ, т.к. своего стабилизатора до 5В не предусматриваю на регуле, питание для мк браться будет с приемника, а там уже толстый стаб стоит. Размер плат, кроме регуля, устраивает вполне. Регуль большой получился, но меньше делать не умею, возможны ошибки в правильности разводки плат. Если кого заинтересовало, то вот еще спринт файл плат, там по вкладкам, как в экселе, все три платы. Принципиальные схемы рисовать отдельно лень, все элементы и так подписаны   Передатчик.lay6
    • Если отсоединить шлейф, то всё получится.
    • у меня пока несколько вопросов осталось ) 1. Я заметно убрал вторую гармонику и добился вполне хорошего показателя - от 0,04% THD. Вернулся в начало темы, посмотрел показатели Василича... Не, ну это фантастика. Хотя, возможно, если убрать фон максимально и понять, как убрать 3-ю гармонику, плюс учесть, что искажения вносятся реверсом - обратным корректором и на компе звуковой картой, так как сам комп вносит ооочень много своих шумов, что слышно при подключении наушников в параллель с фоником ко входу ЗК (уши 150 Омов - ну очень чувствительны ко всему). Собственно, вопрос - каковы варианты убрать 3-ю, самую противную, гармонику? Я даже вторую опустил ниже её. И, судя по тому, что в одном канале она ещё в два раза ниже, чем в другом, то можно и ещё опустить. Но третья остаётся как вкопанная. И всегда равна по каналам. И только ну очнеь большое увеличение 2-й начинает поднимать 3-ю. Но после какого-го момента борьбы со второй, 3-я замирает и всё. Что на неё влияет, что можно покрутить? 2. Возможно фон, как он указан выше, и правда есть. Вспомнилось, что я как-то делал оцифровку (https://yadi.sk/d/R2jzx3hc3JokBd) своим корректором и брендовым от АТ: первопресса Wall: И получил такой вот отзыв: Не об это ли лишнем нч-гуле говориться? (( эх (( Вроде бы петель не делаю по земле, придерживаюсь в этом плане рекомендаций Василича (вроде бы )))),а откуда 50Гц в таком количестве, не знаю (   Да, по THD надо будет попробовать 1кгц пустить с компа точно такого же уровня по амплитуде, как и при измерениях в RMAA, и тогда посмотреть на THD осциллографом.