управление 8канальными модулями реле, через I2C 1602 PCF8574. для новогодней елки

Нет ответов
slider
Offline
Зарегистрирован: 17.06.2014

Мож кому пригодится, чтоб не тратить время на разбирательства.
Задача , управление 6 модулей 8ми канальных реле , без ардуино меги2560, с наименьшими замутами по проводам. Гирлянды на большую елку очень большие, киловатные, поэтому ардуиновские модули твердотельные реле не выдержут. А на симисторах городить некогда , да и купить срочно в местных магазах симисторы будут гораздо дороже чем реле что были в наличии, и паять еще много надо.

Использовались распростаненные переходники (адаптеры ) I2C для дисплеев 1602 2004. Т.о. можно подключить 8..16.. модулей (в зависимости от наличия на переходниках микросхем с разным буквенным индексом PCF8574T 8адресов до 0x3F , PCF8574AT 8адресов до 0x27).

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

Переделка всего одна - перебросить пин:

для подключения друз за дружкой, припаять пины с низа:

из ардуин опробовано на digispark attiny85 

скетч:

#include "PCF8574.h"
#include <Wire.h>

// у PCF8574T 8адресов до 0x3F 
// у PCF8574AT 8адресов до 0x27
// у других модификаций микросхем просканировать скетчем i2c scaner (в инете их полно всяких разных)

//                   A0 A1 A2
PCF8574 M1(0x3F);  // 1 1 1   (не запаяны)
PCF8574 M2(0x3E);  // 0 1 1   (запаяна перемычка слева)
PCF8574 M3(0x3D);  // 1 0 1


void setup()
{
//  Serial.begin(9600);
//  Serial.println("\nTEST PCF8574\n");  
  M1.begin();
  M2.begin();
  M3.begin();
 
// прочтем что на входах , везде должны быть ло.1 на входах (протекает через оптопары в модулях реле)
// uint8_t value = M1.read8();
//  Serial.print("M1:\t");
//  Serial.println(value);

//  M1.shiftLeft();    // сдвинуть
//  M1.shiftRight();   // сдвинуть
//  M1.write(i, 1);    // записать бит
//  M2.write8(x);      // записать сразу байт
//  M1.toggle(i);      // инвертировать бит

// выключим все реле , для наглядности в бинарном виде  b........  .  в hex   0x00
m1(B00000000); 
m2(B00000000);
m3(B00000000);
delay(1000);
}

// *********** ГЛАВНАЯ ПРОГРАММА ****************
void loop()
{
// бегущий огонек:
m1(B10000000); delay(1000);
m1(B01000000); delay(1000);  
m1(B00100000); delay(1000);
m1(B00010000); delay(1000);
m1(B00001000); delay(1000);
m1(B00000100); delay(1000);
m1(B00000010); delay(1000);
m1(B00000001); delay(1000);
m1(B00000000);

m2(B10000000); delay(1000);
m2(B01000000); delay(1000);  
m2(B00100000); delay(1000);
m2(B00010000); delay(1000);
m2(B00001000); delay(1000);
m2(B00000100); delay(1000);
m2(B00000010); delay(1000);
m2(B00000001); delay(1000);
m2(B00000000); 

m3(B10000000); delay(1000);
m3(B01000000); delay(1000);  
m3(B00100000); delay(1000);
m3(B00010000); delay(1000);
m3(B00001000); delay(1000);
m3(B00000100); delay(1000);
m3(B00000010); delay(1000);
m3(B00000001); delay(1000);
m3(B00000000); delay(1000);

// из центра наружу в каждом модуле:
m1(B00011000); 
m2(B00011000);
m3(B00011000); delay(1000);

m1(B00100100); 
m2(B00100100);
m3(B00100100); delay(1000);

m1(B01000010); 
m2(B01000010);
m3(B01000010); delay(1000);

m1(B10000001); 
m2(B10000001);
m3(B10000001); delay(1000);

m1(B00000000); 
m2(B00000000);
m3(B00000000); delay(1000);

// m1(B11111111); delay(2000); // 8 реле потребляют с digispark attiny85     ~0.6 Ампер 

 while (1) {} // СТОП для теста
}

// ******* ФУНКЦИИ ********
void m1(byte x)
{
// отзеркалим байт  для наглядности слева - направо   http://arduino.ru/forum/programmirovanie/razvernut-bait-izmenenie-poryad...
   x = (x & 0x55) << 1 | (x & 0xAA) >> 1;
   x = (x & 0x33) << 2 | (x & 0xCC) >> 2;
   x = (x & 0x0F) << 4 | (x & 0xF0) >> 4; 
// инвертируем байт т.к. реле включается от лог.0  http://arduino.ru/forum/programmirovanie/kak-invertirovat-poluchennye-da... 
  x=~x;
// выведем в порт
M1.write8(x);    
}

void m2(byte x)
{
// отзеркалим байт  для наглядности слева - направо  
   x = (x & 0x55) << 1 | (x & 0xAA) >> 1;
   x = (x & 0x33) << 2 | (x & 0xCC) >> 2;
   x = (x & 0x0F) << 4 | (x & 0xF0) >> 4; 
// инвертируем байт т.к. реле включается от лог.0 
  x=~x; 
// выведем в порт
M2.write8(x);    
}

void m3(byte x)
{
// отзеркалим байт  для наглядности слева - направо  
   x = (x & 0x55) << 1 | (x & 0xAA) >> 1;
   x = (x & 0x33) << 2 | (x & 0xCC) >> 2;
   x = (x & 0x0F) << 4 | (x & 0xF0) >> 4; 
// инвертируем байт т.к. реле включается от лог.0 
  x=~x; 
// выведем в порт
M3.write8(x);    
}
небольшие советы:
 
При использовании таких проводов , желательно их дообжать (встречаются плохообжатые с плохим контактом)
 
Если питать все от одного блока пит. , то ардуину желательно питать через диод шоттки на пин Vcc, и сглажив. кондер на 1000мкф.  (чтоб просадка от реле не распространялась на ардуину, и она продолжла брать энергию с кондера)
 
Модули реле (при большом их количестве) запитать проводами сечением не менее 0,75мм.  К крайним пинам 3пин разъема GND ,  JD-VCC  (желтый джампер снять , можно прицепить на один средний пин VCC чтоб не потерялся)
 
На модулях I2C  7й пин микросхемы (P3) поднять (чтоб не засаживался базой транзистора включения подсветки) , и припаять проводником на 7пин гребенки (если считать от разъема I2C ) . Или припаять как есть , но перерезать дорожку от микросхемы к резистору на +, с транзистором.
 
Для питания 8ми модулей 8ми канальных реле , понадобится мощный блок питания 5в 7А  (100мА*8реле*8модулей) .
 
 
Необязательно:
 
При большом количестве модулей:  желательно на всех модулях I2C, кроме последнего в цепи , выпаять резисторы 4.7кОм с SDA SCL .   Иначе они будут сильно засаживать вывода SDA SCL ардуины.  (к примеру при 10модулях , нагрузка на пин составит не 4.7кОм , а уже 470 Ом . что составит 50% нагрузки на пин. 10мА из 20мА )
 
Общая длина I2C шины желательно до 2х метров.