Ви не увійшли.
І чи обʼявлена вона взагалі. "LedOn" і "ledOn" - зовсім різні ідентифікатори.
А якщо заживлю через звичайний малогабаритний діод? На ньому ж впаде десь 0,7в, плюс захист від переплутаної полярності буде. Тому що 5вт резистор ну добра махіна
Можна і через діод. Але 13.8 В не сильно менше від 14.5. Хоча б два діоди послідовно.
Резистор на 5 Вт - це з трикратним запасом. На резисторі виділятиметься приблизно 1.5 Вт, тобто можна і 2-2.5 ваттний.
І як же реле в блоках автомобіля живляться, на ниж теж 12в надписи
В автомобілі зазвичай ставлять реле, які більш-менш відповідають специфікації. Якщо там написано максимум 15.6 В, то при 15.5 з великою ймовірністю буде працювати довго.
А оці сині реле для самодєлкіних і при номінальних 12 В часто горять.
Якшо нажати Reset, то не щелкає
А якщо:
1. Нажати Reset.
2. Подати живлення.
3. Відпустити Reset.
4. Нажати Reset знову.
5. Зняти живлення.
На яких із етапів щелкає?
1) чи обовязково для підєднання до аварійки гальванічна розвязка? Думаю вона не завадить, просто цікаво.
Якщо на проводі з аварійки не такі ж 5 вольт як на ардуіно, то конвертор рівнів має бути. Якщо там навіть 5 вольт, але не від того ж джерела, що живить ардуіно, то також має бути. А сам конвертор може бути як з гальванічною розвʼязкою на оптопарі, так і без розвʼязки на транзисторі. З оптопарою простіше і надійніше.
2) резистор на 220ом який диапазон номіналів допускається?
Для розповсюдженої PC817 максимально допустимий струм через діод - 50 мА, тобто при 5 В мінімально допустимий резистор: (5-1.25)/0.05 = 75 Ом. Але менше 100 Ом краще не ставити. Впевнено відкривається ця оптопара при 10 мА, тобто обмеження для резистора зверху: (5-1)/0.01 = 400 Ом. Якщо більше, може не спрацьовувати (але ще залежить від струму колектора на виході). 220-330 Ом якраз в оптимумі.
3) резистор на 10ом, яким я перестраховуюсь, чи потрібен він взагалі, а якщо потрібен то які номінали краще?
Кнопка ж замикає провід аварійки на масу накоротко? Заміряйте струм, який іде через провід при замиканні. Якщо менше 40 мА, то резистор не потрібен, там десь уже стоїть інший резистор. Для PC817 максимально допустимий струм колектора - 50 мА.
А, ще питання. При подачі живлення реле вмикається на короткий час і відразу ж вимикається? Чи вмикається і залишається увімкненим, поки є живлення, а при знятті живлення вимикається?
Так як я роблю це людині, то я вирішив перестрахуватись. Звісно для оптопари досить, а для самого реле мабуть ні, а іноді бувають два-три реле
Обмотка реле живиться з піна VCC. IN іде в базу транзистора через резистор, який обмежує струм до одиниць мілліампер. У Atmega328P обмеження на один вивод - 40 мА, одним виводом можна керувати десятком таких модулів. А на весь мікроконтроллер - 200 мА, хоч до кожного піна по реле підключайте.
Якщо ви хвилюєтесь, що не вистачить потужності одного модуля живлення, то струм обмотки реле не більше 100 мА, а Mini-360 видає 1 А запросто. Крім того, на один із модулів живлення навантажено тільки ардуіно, яке в активному режимі споживає максимум пару десятків мілліампер. При такому невеликому споживанні коефіцієнт корисної дії DC-DC суттєво зменшується.
Якщо ж при вмиканні таки виникатиме істотна просадка напруги (що малоймовірно), то поставте по живленню електролітичний конденсатор мікрофарад так на 47-100.
Ось одна з схем, вибачте я незнаю як її по іншому намалювати крім фотошопа наприклад
Нормально, все видно.
В коді у вас піни D4 і D7, на схемі підключено до D8?
Підтягувати не вариант
Коли мікроконтроллер в ресеті, або коли виконується бутлоадер, виводи знаходяться в високоімпедансному стані. Формально логічний стан вивода невизначений, реле "має право" перемикатись як заманеться. На практиці, якщо ключ на біполярному транзисторі, то у вивод в стані INPUT струм не втікатиме і транзистор відкриватись не повинен. Але припустимо, блок що живить реле, набирає напругу трохи швидше того, що живить ардуіно. Струм через транзистор тече в ардуіно і через захистний діод в землю, транзистор відкривається, реле вмикається. При вимиканні можливе те ж саме: конденсатор блока живлення ардуіно розряджається швидше (бо ардуіно споживає струм), а блок живлення реле нічим не навантажений. Із блока живлення реле струм через захисний діод тече в землю, реле вмикається.
Не наполягаю, що у вас відбувається саме так, але такий варіант не виключений.
прошивка зроблена так щоб можно було підєднувати будь яке реле, якщо замкнути D4 на масу то прошивка інвертує сигнал для реле які працюють по HIGH замість LOW, але в мене проблема саме з LOW реле зараз
Ви маєте на увазі цей код?
pinMode(D4, INPUT_PULLUP);
rele_level_kam = digitalRead(D4);
pinMode(D7, OUTPUT);
digitalWrite(D7, rele_level_kam);
Тип модуля реле конфігурується замиканням D4 на землю? Я мав на увазі підтягувати керуючий вивод D7, щоб сигнал мав визначений стан, коли пін ще/вже у високоімпедансному стані (High-Z).
Доречі, не факт, що відразу після вмикання INPUT_PULLUP напруга на D4 встигає встановитись до належного рівня. digitalRead() відразу може і не повернути HIGH.
Також при rele_level_kam=HIGH послідовність 'pinMode(D7, OUTPUT); digitalWrite(D7, HIGH);' виставляє D7 в нуль на короткий час (менше мікросекунди). Сумніваюсь, що цього достатньо для увімкнення реле, але теж слизьке місце.
Пробував ось це реле на 5в, підключення таке саме, перемичку на JDVCC не прибирав
З перемичкою обидва блоки живлення працюють просто в паралель. Тоді дивніше. Може і в логіці програми є помилки, по чотирьом рядкам важко діагностувати.
Для початку спробуйте модуль без оптопотари, заживіть все від одного модуля живлення. Для експеримента модифікуйте прошивку щоб видавала постійну фіксовану полярність (active low) незалежно від стану піна конфігурації. Щоб уникнути глітча при перемиканні піна в OUTPUT HIGH, перемкніть його спочатку в INPUT_PULLUP:
pinMode(D7, INPUT_PULLUP);
pinMode(D7, OUTPUT);
Доречі, а якщо ардуіно примусово утримувати в постійному ресеті, клацає реле при подачі/знятті живлення?
І чи не залишаєте підʼєднаним UART, коли перевіряєте?
nblend() просто оновлює кольорові компоненти відповідно до коефіцієнту перекриття за формулою: X=X*(1-k) + Y*k, де X - колір existing, Y - колір overlay, k = amountOfOverlay/255. Третій параметр - це не step, а коефіцієнт перекриття.
Після оновлення масиву його ще потрібно вивантажити в матрицю. Щоб зробити плавний перехід за 3 секунди, потрібно пробігтись по коефіцієнту перекриття від 0 до 255 з затримкою 3000мс/255, кожен раз оновлюючи масив.
Щось типу такого:
#include <FastLED.h>
#define NUM_LEDS 84
#define DATA_PIN 3
#define NUM_GROUPS 12
#define LEDS_PER_GROUP 7
#define MAX_BRIGHTNESS 255
#define COLOR_CHANGE_INTERVAL 3000 // 3 секунди
CRGB leds[NUM_LEDS];
CRGB groupColors_cur[NUM_GROUPS];
CRGB groupColors_new[NUM_GROUPS];
CRGB groupColors_tmp[NUM_GROUPS];
static CRGB randomColor()
{
return CRGB(random(256), random(256), random(256));
}
static void updateLeds(CRGB colors[NUM_GROUPS])
{
// заповнюєм масив
for (int i = 0; i < NUM_GROUPS; i++) {
for (int j = 0; j < LEDS_PER_GROUP; j++) {
leds[i * LEDS_PER_GROUP + j] = colors[i];
}
}
// вивантажуєм оновлені кольори в матрицю
FastLED.show();
}
void setup()
{
FastLED.addLeds<WS2812, DATA_PIN, GRB>(leds, NUM_LEDS);
FastLED.setBrightness(MAX_BRIGHTNESS);
randomSeed(analogRead(0));
// початкові значення колорів
for (int i = 0; i < NUM_GROUPS; i++) {
groupColors_cur[i] = randomColor();
}
}
void loop()
{
// відображаєм статичні кольори 3 секунди
updateLeds(groupColors_cur);
delay(COLOR_CHANGE_INTERVAL);
// кінцеві значення кольорів
for (int i = 0; i < NUM_GROUPS; i++) {
groupColors_new[i] = randomColor();
}
for (int k = 0; k <= 255; k++) {
memcpy(groupColors_tmp, groupColors_cur, sizeof(groupColors_tmp));
for (int i = 0; i < NUM_GROUPS; i++) {
nblend(groupColors_tmp[i], groupColors_new[i], k);
}
updateLeds(groupColors_tmp);
delay(COLOR_CHANGE_INTERVAL/255); // весь цикл виконується приблизно за 3 с плюс час на виконання коду і вивантаження масиву в матрицю
}
// замінюєм поточні значення кінцевими для наступної ітерації
memcpy(groupColors_cur, groupColors_new, sizeof(groupColors_cur));
}
Код не перевіряв, бо не маю такої матриці світлодіодів. Досить неоптимально і десь можуть бути помилки. Але основна ідея має бути зрозумілою.
Живлення на arduino подаю через окремий DC-DC перетворювач mini-360 на вход VIN
Живлення на VCC реле подаю від окремого DC-DC перетворювача mini-360 (тому що боюсь що D-вихід не витримає навантаження на реле по струму), GND загальний.
Взагалі-то в модулі реле обмотка живиться від джерела живлення через транзисторний ключ, а не з керуючого входу. Струму в порт (до 40 мА) має вистачити як для вмикання оптопари, так і для вмикання транзисторного ключа напряму, якщо без оптопари.
Покажіть схему підключення.
Джампер VCC - JD-VCC на модулі реле знято?
При неправильно спроектованій схемі з двома джерелами живлення, коли одне з них вимкнене, або при деяких інших умовах, струм з іншого може пролазити в "не свою" частину через захисні діоди.
Здається, два джерела живлення там зайві, можна обійтись одним.
Проблема в тому що при подачі живлення або при знятті живлення на всю схему реле короткочасно спрацьовує на долю секунди. Як можно обійти цю проблему?
Спробуйте підтягнути керуючий сигнал зовнішнім резистором в 1-10 кОм до живлення. Але краще покажіть схему. Якщо спрацьовує і при знятті живлення, то це явно не програмна проблема, а глітчі по живленню.
Я правильно понял, все через логическое XOR и в конце, через И ?
Так, щось типу такого:
unsigned char pkt[] =
// 0 1 2 3 4 5 6
{ 0xFF, 0xFF, 0x07, 0x00, 0x07, 0x00, 0x00 }; // cmd STAT, no data
for (int id = 1; id <= 20; ++id) {
pkt[3] = id;
pkt[5] = 0; // zero check_sum_1
pkt[6] = 0; // zero check_sum_2
unsigned char checksum = 0;
for (int i = 2; i < sizeof(pkt); ++i) {
checksum ^= pkt[i];
}
pkt[5] = checksum & 0xFE;
pkt[6] = ~pkt[5] & 0xFE;
send_packet(pkt, sizeof(pkt));
wait_response();
}
Дивний і ненадійний алгоритм контрольної суми, але так написано
Протоколы все перепробовал, качал еще пару альтернативных программ
Я би все-таки спробував той протокол, що для A1-16. Тільки не сторонньою програмою, а своєю, щоб гарантовано видавала правильно сформований пакет. Наприклад, STAT для ID 1: 0xFF 0xFF 0x07 0x01 0x07 0x01 0x00. З перебором ID від 1 до 20 і перерахуванням байтів контрольної суми. Також з перебором чотирьох бодрейтів. І дивитись, чи прийде відповідь хоч на один. Всього-то 80 варіантів Ну або впевнетись, що альтернативні програми генерують пакет, відповідний протоколу.
На плате сервопривода, два резистора 1кОм припаяны вместе, отводы распаяны на разные входы микросхемы.
А видно маркування мікросхеми? Чи можна змалювати схему, хоча б частково, куди подається вхід, земля і живлення? Або фото плати?
Документ, что прилагается не от него, от похожего
А він точно з керуванням по послідовному протоколу?
На сайті виробника по назві DM0900 знаходиться два серво:
DM0900 10.5KG Digital Metal Gear Servo
Digital Metal Gear Servo DM0900
Обидва з PWM-керуванням. У маркетологів PWM також вважається "digital"
Може в описі товару тупо переплутали, написавши про послідовну шину. Таке буває.
Так, програма у вас видає Dynamixel Protocol 1.0.
Ще є Protocol 2.0. А на сторінці товару посилання на даташит для A1-16, де протокол схожий, але несумісний ні з Dynamixel 1.0, ні з 2.0. Кожен виробник модифікує протокол як хоче, аби було несумісно з продукцією конкурентів.
Готового решения сразу не нашел )
Теоретично, якщо зі сторони серво відкритий колектор з підтяжкою, то одного діода Шотткі з серво на TX має бути достатньо. Принаймні debugWIRE для AVRок у мене так працює без проблем.
Але мені все ж здається, що там не послідовний протокол, а звичайний PWM.
Доречі, в прошивці для Attiny не бачу конфігурування CLKPR. Якщо Attiny працює від внутрішнього осциллятора на 9.6 МГц і фʼюз CKDIV8 не скинуто, то його тактова частота - 1.2 МГц. Один такт - це біля 10% від такту для 115200 бод. Далеко не всякий UART буде нормально працювати при такій похибці.
Неделю не могу подружить сервопривод с компом.
Покажіть cхему підключення і код керування. Чи відповідає servo ID в коді дійсному ідентифікатору серво? Покажіть дамп трафіку пакетів. Чи видає серво підтвердження прийому пакетів? Чи пробували різні бодрейти UART: 9600, 19200, 57600, 115200?
Мне просто нужно что-бы схема могла включить и выключить +12v.
Явних помилок не бачу, має працювати. Постійна часу R3 * ємність затвор-виток суттєво менша періоду PWM PCA9685PW, так що ок.
D3 - защитный диод
Ага, якщо передбачається індуктивне навантаження, тоді ок. Хіба що зверніть увагу на відвід тепла, бо при великих струмах і середньому заповненні PWM діод може грітись.
Компілюєте і прошиваєте з arduino IDE? Чи правильно вибрана плата, і особливо частота кварца? Замініть myservo.write() на блимання світлодіодом, перевірте, чи правильно працює delay() взагалі.
Якщо є осциллограф, подивіться, що за сигнал іде з керуючого вивода з ардуіни.
Чи не підключено занадто довгими проводами? Спробуйте підключити якомога коротшими.
Чи буде моя схема коректною для керування PWM сигналом?
На схемі VCC 12V між діодом і стоком мосфета - помилка? Що за GND зверху? Для чого діод?
Наскільки мені відомо, у вентиляторах з PWM-керування керуючий сигнал подається на затвор вбудованого мосфета, який вже підтягнутий до живлення. Тобто достатньо просто замикати вивід PWM на землю. Теоретично одного біполярного транзистора має бути достатньо. Для інверсного керування (нуль - повна потужність) - по схемі з загальним еміттером, для прямого - з загальною базою, підтягнутою до живлення керуючої схеми.
Але ж нам не відомо, яка саме внутрішня схема вашого вентилятора. Поміряйте, чи є там підтягуючий резистор між входами PWM і 12V? Якщо є, то чи зупиняється вентилятор при замиканні PWM на землю?
Керування ШІМ та бездротова передача - різні задачі, хоча і можуть бути вирішені одним апаратним засобом.
Які вимоги до частоти і розрядності ШІМ, кількість каналів? Що є джерелом керуючого сигналу?
Протокол бездротової передачі також обирається в залежності від вимог: дальність, діапазон частот, надійність, споживання енергії.
Одним із варіантів може бути пара ESP8266 або ESP32: один в режимі WiFi Access Point, другий в режимі WiFi Station. Трохи надмірно для такої задачі, але просто в реалізації.
Інший варіант: окремо безпровідна передача, наприклад радіомодулі UART, і окремо будь-який мікроконтроллер з UART і ШІМ для виконавчої сторони і з UART і необхідним вхідним інтерфейсом для контролюючої.
Один із найпростіших, мабуть, варіантів:
constexpr byte PIN_BUZZER { 3 };
constexpr byte PIN_BUTTON { 12 };
constexpr byte debounce_ms { 50 };
void setup() {
pinMode(PIN_BUTTON, INPUT_PULLUP);
}
void loop() {
constexpr unsigned int freq[] = { 14000, 15000, 16000, 17000 };
byte idx = 0;
for (;;) {
tone(PIN_BUZZER, freq[idx]);
unsigned long start_ms = millis();
do {
if (digitalRead(PIN_BUTTON) == LOW) {
start_ms = millis();
continue;
}
} while ((millis() - start_ms) < debounce_ms);
while (digitalRead(PIN_BUTTON) == HIGH) {};
if (++idx >= sizeof(freq)/sizeof(*freq)) {
idx = 0;
}
}
}
Припускається, що випромінювач звуку підключений до піна 3, кнопка до піна 12 і замикається на землю.
В такій реалізації процесор постійно споживає струм в активному режимі. Якщо потрібна економія споживання при автономному живленні, необхідно задіяти функції енергозбеження і переривання.
Як на активному зуммері можна отримати різні тони (ноти)?
Хе, слушне зауваження. Мені спочатку здалося, що під активним мається на увазі - з вбудованим буферним каскадом.
Якщо ж під активним мається на увазі - з автогенерацією (а судячи по маркуванню на фото, так і є), то звісно що ніяк. Хіба що змінюючи напругу живлення можна отримати якусь непередбачувану невеличку девіацію частоти
Є код, не спаплюжений автоперекладачем?
В цьому "коді", як можна зрозуміти, налаштування кожного таймера зберігається в EEPROM у такому форматі:
#байта значення
0 активний/неактивний
1 година увімкнення
2 хвилина увімкнення
3 година вимкнення
4 хвилина вимкнення
5 номер канала
6 рівень сигнала
7 бітова маска днів тижня
Тобто час задається дискретно по хвилинах.
Щоб зробити по секундах, можна доповнити структуру ще двома полями: секунда увімкнення і секунда вимкнення. Тоді в обчисленні часу замість
timeTimerStart = (uint32_t)funcReadTimer(i, 1) * 3600 + funcReadTimer(i, 2) * 60;
timeTimerStop = (uint32_t)funcReadTimer(i, 3) * 3600 + funcReadTimer(i, 4) * 60;
буде щось типу
timeTimerStart = (uint32_t)funcReadTimer(i, 1) * 3600 + funcReadTimer(i, 2) * 60 + funcReadTimer(i, 8);
timeTimerStop = (uint32_t)funcReadTimer(i, 3) * 3600 + funcReadTimer(i, 4) * 60 + funcReadTimer(i, 9);
Тоді структура займатиме 10 байт замість 8-ми, тому потрібно змінити індексування EEPROM:
uint8_t funcReadTimer(uint8_t i, uint8_t j) {
return EEPROM[i * 10 + j];
}
...
void funcSaveTimer(uint8_t i, uint8_t j, uint8_t k) {
EEPROM[i * 10 + j] = k;
}
і решту коду, де очікується 8-байтова структура. Відповідно зміниться і кількість доступних таймерів з "кількість байт EEPROM/8" на "кількість байт EEPROM/10".
Також знадобиться додати установку секунд в UI.
Якщо буде достатньо дискретності в 2 секунди (тобто тільки 0, 2, 4, .. 58 секунд), то можна упакувати поле часу в ті ж два байта і обійтись без зміни розміру структури: 5 біт на години, 6 біт на хвилини і 5 біт на секунди. Або зберігати час просто як кількість 2-секундних інтервалів від початку доби.
UPD: ще, щоб не змінювати розмір структури, але отримати дискретність в 1 секунду, можна використати біти з нульового байта структури і упакувати додаткові біти секунд у нього.
В чому полягає питання? Звідки -38?
Ви вводите два символи: '3' і перевод строки з кодом 10. 10 - 48 (код символу '0') = -38.
Що вже працює і на якому етапі перестає?
GSM-модуль реєструється в мережі? Отримує IP-адресу?
Вдається встановити TCP-зʼєднання хоч з яким-небудь сервером, без передачі даних? Наприклад, з будь-яким працюючим web-сервером на порт 443?
Ваш хост, який ви плануєте використовувати в ролі сервера, має глобальну (білу) IP-адресу? Якщо ні, то прокиньте порт на свій хост на роутері. Спробуйте встановити зʼєднання з девайса на вашу глобальну адресу і цей порт. У wireshark маєте побачити хоча би спробу TCP зʼєднання (SYN-пакет). Потім запустіть той же socat, чи netcat, чи що там є під вашу операційну систему.
шлях до бібліотек я вставляла в c_cpp_properties.json, який я скинула вище
Налаштування в c_cpp_properties.json впливають на збірку вбудованими в VSCode засобами та на IntelliSense. На збірку проекту зі стороннім Makefile вони не впливають.
Ваш Makefile не підходить для збірки ардуіно-скетчів. Як мінімум, він компілює проект на C, а скетчі пишуться на C++. Проблему з #include <OneWire.h> можна вирішити, додавши "INCLUDE += -I<шлях_до_хідера>". Але це вам не допоможе, тому що бібліотеку потрібно ще теж скомпілювати і прилінкувати. В принципі, і ваш Makefile можна адаптувати для компіляції C++, компіляції бібліотеки і лінковки з нею. Але простіше буде, як порадили вище, взяти готове рішення у вигляді arduino-mk.