Ви не увійшли.
Сторінки 1
Соединил две ардуины через модули TTL-RS485 по стандартной схеме. Одна ардуина измеряет напряжение на переменном резисторе и передаёт на вторую. Передача только в одну сторону. Связь работает, но при изменении напряжения приёмник принимает данные с задержкой 20 секунд. Приём и передачу контролирую в мониторе. Скорость связи менял 4800, 9600, 19200 - результат - задержка не изменилась. При изменении данных на передатчике через 10 секунд разрывал линию - на приёмнике с задержкой показания менялись! То-есть, приёмник принимает данные сразу, но "отдаёт" с задержкой 20 секунд. В приёмнике реализовано только приём данных и просмотр(контроль) в мониторе. Линия связи - витая пара, 40 м.
Остання редакція tss69 (2024-12-09 12:58:53)
Неактивний
MAX485 не містить ніякої логіки і буферів. Якщо затримка 20 секунд, але дані таки приходять, то вони десь мають зберігатись. Це явно програмна помилка. Потрібно розуміти, на якій із сторін відбувається ця затримка. Не завадило би подивитись на код приймача і передавача.
Неактивний
Я це розумію, тому і питаю, можливо хтось мав досвід? Код дуже простий.
Приймач:
#include <SoftwareSerial.h>
SoftwareSerial RS485(6,7);
#define DE_RE 10 // управление модулем RS485 прием-передача
float R2;
void setup()
{
Serial.begin(9600);
RS485.begin(4800);
pinMode(DE_RE,OUTPUT);
digitalWrite(DE_RE,LOW); //приемник
}
void loop()
{
R2=RS485.read();
Serial.print("Zadanie = ");
Serial.println(R2,0);
delay(200);
}
Передавач:
#include <SoftwareSerial.h>
SoftwareSerial RS485(6,7);
#define DE_RE 10
float R;
float R1;
void setup()
{
Serial.begin(9600);
RS485.begin(4800);
pinMode(DE_RE,OUTPUT);
digitalWrite(DE_RE,HIGH); //передатчик
}
void loop()
{
R1 = analogRead(A0);
R =(R1+1)/4;
Serial.print("ZADANIE = ");
Serial.println(R,0);
RS485.write(R);
delay(10);
}
Остання редакція tss69 (2024-12-09 20:48:10)
Неактивний
Мені здається що затримка у приймачі. Як я описував, поведінка приймача така, що при зміні показів із затримкою в 5-10 секунд я фізично роз"єдную дроти, але приймач із затримкою потім показує принятий вірний результат.
Остання редакція tss69 (2024-12-09 20:59:03)
Неактивний
Знайшов причину затримки. У кінці коду приймача є команда затримки delay(200). Після заміни на delay(10) затримка зникла. Якщо замінити на delay(100), тоді затримка становить 10 секунд. Таку затримку використовув коли для налагодження роботи підключав тимчасово дисплей 1602.
Неактивний
Код дуже простий.
Простий не значить правильний.
1. В приймачі ви намагаєтесь читати дані навіть коли їх нема. SofSoftwareSerial::read() при цьому повертає -1.
2. В передавачі затримка між посилками 10мс (+ якийсь час на виконання інших функцій). В приймачі затримка між спробами читання 200 мс. Приймач навіть теоретично не встигатиме читати всі відправлені передавачем дані. Навіщо взагалі в приймачі ця затримка 200 мс?
3. Кожну ітерацію в UART пишеться більше десятка байт ("Zadanie = " плюс саме значення та r). На 9600 бод їх передача займає більше 10 мс. В передавачі з часом внутрішній буфер Serial заповнюється і Serial.print() блокує виконання поки буфер не звільниться.
До проблеми не відноситься, але все ж:
4. Навіщо там використання типу float?
Я би порадив для початку відлагодити комунікацію при безпосередньому TTL-зʼєднанні приймача з передавачем. Тільки після того як все працюватиме правильно, зʼєднувати по RS485.
Неактивний
Якщо замінити на delay(100), тоді затримка становить 10 секунд.
Навіщо там взагалі delay()? В 99.9% випадків, якщо в коді delay(), значить щось не так із кодом або алгоритмом в цілому.
Неактивний
У деяких прикладах при роботі з analogRead(A0) використовували delay(10) перед зчитуванням.
Використання serial.println() потрібно було для контролю, у готовому приладі використовуватись не буде.
Тип float - під час випробувань приєдннував 1602, простіше(без перетворювання типів змінних) у використанні.
Остання редакція tss69 (2024-12-10 01:17:18)
Неактивний
У деяких прикладах при роботі з analogRead(A0) використовували delay(10) перед зчитуванням.
Затримка перед читанням ADC мала би сенс після вмикання внутрішнього джерела опорної напруги, щоб воно встигло стабілізуватись. Даташит говорить про час стабілізації 40-70 мікросекунд.
Ардуіно, по-перше, в якості опорної напруги за замовчуванням використовує Vcc; по-друге, конфігурує ADMUX всередині analogRead(). Так що затримка перед analogRead() не має жодного сенсу. Просто зробіть одне читання в setup() та проігноруйте його результат.
Якщо передавач має зчитувати та відправляти дані з певною частотою, то краще вже використовуйте millis().
На приймачі взагалі ніяких затримок не потрібно.
Використання serial.println() потрібно було для контролю, у готовому приладі використовуватись не буде.
Просто майте на увазі, що відправлені в Serial дані хоч і буферизуються, але їх передача з буфера потребує часу. Щоб мінімізувати вплив дебажного вивода на роботу, використовуйте вищий бітрейт, наприклад 115200.
Тип float - під час випробувань приєдннував 1602, простіше(без перетворювання типів змінних) у використанні.
1602 - це алфавітно-цифровий дисплей? Не дуже зрозумілий його звʼязок з float. Ну то таке.
Неактивний
Використовуйте SoftwareSerial.available(), а синхронізація на delay() це дуже погано.
Сторінки 1