Ви не увійшли.
вот что выходит:https://forum.arduino.ua/img/members/373/oshibka-kompiljacii.png
Так схоже, що бібліотека з ADS9850 у вас не встановлена. Лінкер не знаходить, звідки брати ті функції. До компіляції це не має відношення.
"exit status 1 ошибка компиляции для платы Arduino NANO"
Ви користуєтесь Arduino IDE? Зайдіть у налаштування та увімкніть "Show verbose output during: compile". Я х.з. як воно в локалізованому варіанті, щось типу "Показывать подробный вывод при: компиляции".
Как вставить код в тексте - подскажите
Тег
[code]
[==C++==]
тут ваш код
[/code]
Це оператор вам сказав що "вимкнення 2G" чи це ваше припущення?
У мене ще в 2020 році пара SIM800 перестала зʼєднуватись. І на смартфоні передача даних при перемиканні мережі на 2G перестала працювати. Але необхідність у тих модулях відпала, тому взагалі забив на стільниковий звʼязок і не шукав альтернатив.
Прошу помощи - при компиляции скетча пишет ошибка компиляции.
Для початку скопіюйте текст помилки і вставте у повідомлення текстом. Також бажано код вставити текстом, щоб було, зрозуміло де в коді який номер рядка.
Ще би бажано описати, яке призначення вашого коду, що ви намагаєтесь реалізувати.
Так більше шансів отримати допомогу.
проблему вирішено за допомогою chat GPT
Не вірю.
коли подається сигнал із датчика вмикається реле потім вимикається через вказаний час але коли зникає сигнал із датчика знову вмикається реле на вказаний час і вимикається,в чому ж проблема?
Може бути, що перед тим як зникнути сигнал тіліпається туди-сюди (той самий брязкіт), і відбувається перехід із високого рівня в низький, потім назад у високий. Я ж не знаю, що там за датчики і який характер сигналу на вході. Код розрахований на чіткі фронти.
Але додавати туди ще й фільтрацію по таймінгам - дійсно, простіше все з нуля переписати. У вигляді нормального конечного автомата.
Може бути і якась інша причина. Повставляйте Serial.print() у ключові точки та подивіться, що там відбувається.
PS: Опитування кнопок у вас чомусь під "if (input != input1_prev)" попало. Воно має бути ззовні блока if.
Board_4ch_delay_relay:189:9: error: 'Interrupts' was not declared in this scope
А, це моя помилка. Воно "interrupts()", з маленької "i".
Хотів же ще cli() / sei() написати, але вирішив по-ардуінівськи
в такому вигляді запрацювало,але при подачі сигнала реле спрацьовує і не відключається.таймер не працює
Звісно, обробку переривань вимкнули, а назад не увімкнули. Я б здивувався, якби запрацювало
Board_4ch_delay_relay_4ch_delay_relay.ino:110:20: warning: large integer implicitly truncated to unsigned type [-Woverflow]
Тут у вас 1000 не влазить в unsigned char. Максимум можна 255. І замість 1000 у вас записується 232.
А якщо тупо збільшите розрядність OneSecondCnt, тоді оте переповнення у OneSecondCnt-- створить на початку роботи затримку на 65535 одиниць замість 255.
Як обхідний варіант можете таки замість того "uchar OneSecondCnt;" зробити
unsigned int OneSecondCnt = 1;
Хоча по-хорошому, всю ту "логіку" потрібно переписувати.
не підходить ця частина коду,помилка коомпіляції для ардуіно про міні,ще щось можете порадити?
Яка саме помилка? Скопіюйте сюди її повний текст.
Куди і замість якої частини цю частину вставили? Який вигляд має loop() після зміни?
Для одного реле
bool input1_prev { false };
// в loop():
bool input = (digitalRead(INPUT1)==LOW);
if (input != input1_prev) {
if (input) {
noInterrupts();
relay1_time_left = relay1_delay_time;
digitalWrite(j1, HIGH);
Interrupts();
}
digitalWrite(led, input); // тут один led на 4 канала?
input1_prev = input;
}
Щоб не дублювати код для кожного канала, зробіть масив.
Викиньте "while(1) {...}" із loop().
Можна легко обійтись без отого FlexiTimer2, воно тільки ускладнює програму.
А краще найміть спеціаліста, в якого є час і натхнення, нехай напише вам нормальний код.
так і задумано щоб реле вмикалось при подачі низького рівня від датчика але потрібно щоб незележно від того наскільки довго подається сигнал з датчика реле відпрацювало і вмикалось далі до того часу поки не буде наступного сигналу,тому що зараз якщо сигнал з датчика перевищує час відпрацювання реле то реле включається повторно
У вас є вхід з двома станами: низький / високий рівень (можливий брязкіт контактів поки до уваги не берем).
Є вихід з двома станами: реле вимкнене / увімкнене.
Є внутрішній стан таймера: активний / неактивний.
Це вже дає 8 можливих комбінацій (частина з них потім редукується). Для початку намалюйте діаграму або таблицю переходів. Для кожного переходу визначте умову (стан входу, стан таймера), а також дії, які мають виконатись (увімкнути/вимкнути реле, запустити таймер і т.п.).
Поки реле увімкнене, повторний перехід з високого на низький рівень на вході має перезапускати таймер? Чи стан вхіду має значення тільки після вимкнення реле?
прикріплю скріни з кодом
Не робіть так. Ви б ще аудіоповідомлення з кодом надиктували.
є готовий скетч під це діло
В тому скетчі одразу впадає в очі як мінімум один баг: TubeDisplay4Bit() виконується в контексі переривання і читає та пише int relay*_time_left. В loop() ці змінні також модифікуються без будь-якої синхронізації.
Також uchar OneSecondCnt як глобальна змінна ініціалізована нулем, потім
OneSecondCnt--;
if(OneSecondCnt==0) ...
Тобто переходить через переповнення - навряд чи так було спеціально задумано.
Ще купа інших недоліків у тому коді, але про них поки промовчу.
але проблема заключається в тому що при подачі сигналу реле часу працює циклічно,тобто реле умовно відпрацювало 5 секунд а сигнал поступає нерозривно більше 5 секунд і реле часу спрацьовує знову а потрібно щоб незалежно від часу на який подається сигнал реле відпрацювало умовно 5 секунд і відключилось до моменту поки не буде наступного сигналу
Так у вас умова вмикання реле - це низький рівень на вході:
if (digitalRead(INPUT1)==LOW) { ... digitalWrite(j1, HIGH);digitalWrite(led, HIGH); } ...
А умова вимикання - закінчення відліку лічильника
if (relay1_time_left>0) { ... } else { digitalWrite(j1, LOW); relay1_display = relay1_delay_time;}
Як сказано у коментарі вище, потрібно перемикати стан не по значенню рівня на вході, а по факту зміни цього рівня.
Але мені здається, набагато легше буде написати нормально з нуля, чим виправляти той "готовий" гів код.
0h: 37
1h: 38
2h: 0
3h: 1
4h: 1
5h: 1
6h: 0
Ну це 00:26:25 01.01.2000 (2000 + 0), нормальні значення після скидання.
7h: 0
8h: 0
9h: 0
Ah: 0
Bh: 0
Ch: 0
Dh: 0
Будильники не заведені.
Eh: 28
Fh: 136
10h: 0
11h: 21
12h: 192
EOSC (старший біт в регістрі 0Eh) тепер скинутий. Значення регістрів дивіться в таблиці на стр. 11 в даташиті.
У вас взагалі на лініях I²C є pull-up резистори?
На дисплей виводиться 2000+year)))
Тобто змінна year має значення 165. Воно може бути отримане від bcdToDec() при аргументі 255: 15*10 + 15.
У вас або Wire.read() повертає -1 (немає даних в буфері), або відвалилась SDA і читаються всі одиниці.
Спершу додайте перевірку результату Wire.read() на -1. Якщо що, Wire.read() повертає int, а не byte.
Якщо там проблема зі зʼєднанням по I²C, то аналізувати подальший код немає сенсу, поки цю проблему не буде виправлено. Нажаль, Wire - жахливо написана бібліотека, і з нею діагностувати помилки комунікації не так то просто.
Доречі, назви функцій bcdToDec() та decToBcd() невдалі, BCD саме по собі Dec. Назви мали би бути щось типу bcdToInt() та intToBcd().
Не дуже розумію, навіщо читати значення в BCD, конвертувати його в число, а потім число знову в BCD, щоб відображати на дисплеї. Але то таке.
Я навіть не знаю, як з ними працювати, ніколи не стикався.
Так само як читаєте регістри годинника та календаря, тільки всі 19 регістрів:
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.write(0);
Wire.endTransmission();
size_t len = Wire.requestFrom(DS3231_I2C_ADDRESS, 19);
Serial.print("requestFrom() = ");
Serial.println(len);
for (int i = 0; i<19; i++) {
Serial.print(i, HEX);
Serial.print("h: ");
Serial.println(Wire.read());
}
Нічого тада не записував
Значить якось записалось. Це найперша очевидна причина зупинки осцилятора при живленні від батарейки.
Відʼєднайте зовнішнє живлення та батарейку. На пару секунд закоротіть контакти гнізда куди вона підключається, щоб розрядити ємності. Вставте батарейку назад.
Теж саме - при вимкненні живлення годинник зупиняється (((((
А ви часом ніде не записали одиницю в біт EOSC?
Здампте вміст всіх регістрів та подивіться вже, що там робиться.
Цікаво, як цей код може видавати "2165 рік", коли
byte ... year;
...
Serial.print(year);
Або це не той код, або щось недоговорюєте.
Деякі недоліки в приведеному коді є, але не такі щоб призводили до результату що спостерігається.
Які "сирі" значення повертає Wire.read() ?
Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
for (int i = 0; i < 7; i++)
Serial.println(Wire.read());
Та мабуть же код для нано непортабельний, покладається на особливості 8-бітної AVR. А на 32-розрядній системі виліз страшний Undefined Behavior.
Саме годинник ds3231.
зараз на них 2165 рік, 25 годин, 104 місяць))))
Десь неправильно інтерпретуєте прочитанні значення. У DS3231 календар та годинник у BCD форматі. Наприклад, на місяць відводиться всього 5 біт, так що 104 вона ніяк не може видавати.
Показуйте код.
В ту штуку до на малюнку для зарядки треба подавати 9В.
Не треба на BMS подавати 9В, якщо в BMS немає функції обмеження зарядного струму та зупинки заряду. Хіба ця BMS містить в собі зарядний контролер?
Маю железяку з камнем 8515 та 7-сегм. індікатором, ноги якого розведені на різні порти. от і горожу город, а він не городится.
Класичний приклад проблеми XY. "Привʼязувати біти змінної" для цієї задачі зовсім не потрібно.
Навіщо вам змінна? Напишіть просту функцію, яка розпихує біти в різні порти.
Наприклад, нехай індикатор підʼєднаний наступним чином:
A - PORTB.0
B - PORTB.1
C - PORTB.2
D - PORTD.0
E - PORTD.1
F - PORTD.3
G - PORTD.2
У вас є значення, в якого біт 0 відповідає сегменту A, біт 1 - сегменту B і т.п.
Тоді просте рішення "в лоб":
void display(byte v)
{
PORTB = (v & 0b0000111) | (PORTB & ~0b0000111);
PORTD = ((v & 0b0011000) >> 3) |
((v & 0b0100000) >> 2) |
((v & 0b1000000) >> 4) | (PORTD & ~0b0001111);
}
Потім викликаєте цю функцію. Наприклад, цифрі "4" відповідає значення 0x66:
display(0x66);
// або, те ж саме
display(0b1100110);
Якщо потрібно мінімізувати затримку між оновленням сегментів, тоді спочатку обчислюєте значення, потім їх записуєте в регістри:
void display(byte v)
{
byte portb = (v & 0b0000111) | (PORTB & ~0b0000111);
byte portd = ((v & 0b0011000) >> 3) |
((v & 0b0100000) >> 2) |
((v & 0b1000000) >> 4) | (PORTD & ~0b0001111);
PORTB = portb;
PORTD = portd;
}
Якщо сегменти вмикаються нулем (спільний анод), тоді просто передаєте інвертоване значення.
Якщо у вас труднощі з бітовими операціями, то напишіть який сегмент до якого піна підключений, допоможемо.
Також можна написати більш універсальну функцію, для якої мапінг сегментів на піни задається у вигляді таблиці.
EDIT: виправив бітові маски та вирівняв відступи для наглядності.
b+ b- дають десь 8 вольт. - не підключено нічого,
Звідки пристрій, до якого не підключено нічого, може давати 8 вольт? Мабуть на P+ P- все ж таки щось подаєте?
З входами b+ b- bm p+ p-. P+p- - дають максимум 3 вольти - нічого не підключено
Те ж саме, звідки на P+ P- може бути напруга, якщо нічого не підключено?
bms 2s - такий як на скріні, з чотирьма чіпами 8205A
8205A - то мосфети. Контролер BMS - це ота маленька шестинога U1.
Arduino Mega 2560, A4988, NEMA 17
Пошукав для вас:
https://lastminuteengineers.com/a4988-stepper-motor-driver-arduino-tutorial
https://how2electronics.com/control-stepper-motor-with-a4988-driver-arduino
https://miliohm.com/how-to-drive-a-stepper-motor-easily-using-a4988-and-arduino
https://howtomechatronics.com/tutorials/arduino/how-to-control-stepper-motor-with-a4988-driver-and-arduino
https://www.instructables.com/Drive-a-Stepper-Motor-with-an-Arduino-and-a-A4988-
https://www.diyengineers.com/2022/04/21/a4988-how-to-use-with-arduino-or-nodemcu-esp8266
https://www.youtube.com/watch?v=psI3aN0A-OA
Хочу міняти стан пінів порту через змінну D. При зміні значення D мае мінятись стан пінів порту B i D . молодші біти D Змінюють молодші біти порту В , старші біти D змінюють старші біти порту D .
Зміна стану пінів порта - це запис значень в регістр ввода-вивода, який знаходиться за певною адресою. Присвоєння значення звичайній змінній фундаментального типу (яким є unsigned char aka byte) - це запис значення в іншу адресу, де ця змінна розташована. Хоча фактичного запису в ОЗУ може і не бути, якщо компілятор так вирішить
Якщо ви хочете перехоплювати звернення до певних адрес ОЗУ, то на процесорі без MMU, яким є Atmega, це неможливо.
Якщо ви хочете, щоб при присвоєнні виконалась певна _дія_ (бітові операції над значенням та запис в регістр ввода-вивода), то створюйте клас і перевантажуйте оператор присвоєння, як у прикладі вище.
Як взагалі написати змінна А дорівнюе третьому біту змінноі D ?
A = (D >> 3) & 1;
Також можна:
A = (D & 8) >> 3;
що можна записати як
A = (D & (1u << 3)) >> 3;
Загальний випадок для будь-якого біта n:
A = (D >> n) & 1;
Маю змінну byte D . Хочу привязати біти D до пінів частково порту В та D щоб змінювать стан портів виразом
на приклад D = B01010101 .
Що значить "привʼятази біти"? Ви хочете, щоби при присвоєнні значення змінній виконувався певний код? Зі змінною фундаментального типу так не вийде. Можете створити клас із перевантаженим оператором присвоєння, наприклад:
struct composite_port
{
unsigned char operator=(unsigned char v)
{
PORTB = (PORTB & ~0x20) | ((v << 5) & 0x20); // 0-й біт значення у 5-й біт PORTB
PORTD = (PORTD & ~0x08) | ((v << 2) & 0x08); // 1-й біт значення у 3-й біт PORTD
return v;
}
};
Потім
composite_port D;
D = 0x3;
або просто
composite_port{} = 0x3;
Але навіщо вам це? Яку проблему намагаєтесь вирішити такою конструкцією?