Відповісти

Введіть повідомлення і натисніть Надіслати
Параметри

Назад

Огляд теми (нові повідомленні вгорі)

dimich
2024-12-10 17:27:04
ihor пише:

Використовуйте SoftwareSerial.available()

Якщо читати посимвольно, то і available() не потрібно.

int c = serial.read();
if (c != -1) {
...
}
ihor
2024-12-10 14:09:18

Використовуйте SoftwareSerial.available(), а синхронізація на delay() це дуже погано.

dimich
2024-12-10 04:15:27
tss69 пише:

У деяких прикладах при роботі з analogRead(A0) використовували delay(10) перед зчитуванням.

Затримка перед читанням ADC мала би сенс після вмикання внутрішнього джерела опорної напруги, щоб воно встигло стабілізуватись. Даташит говорить про час стабілізації 40-70 мікросекунд.
Ардуіно, по-перше, в якості опорної напруги за замовчуванням використовує Vcc; по-друге, конфігурує ADMUX всередині analogRead(). Так що затримка перед analogRead() не має жодного сенсу. Просто зробіть одне читання в setup() та проігноруйте його результат.

Якщо передавач має зчитувати та відправляти дані з певною частотою, то краще вже використовуйте millis().
На приймачі взагалі ніяких затримок не потрібно.

tss69 пише:

Використання  serial.println() потрібно було для контролю, у готовому приладі використовуватись не буде.

Просто майте на увазі, що відправлені в Serial дані хоч і буферизуються, але їх передача з буфера потребує часу. Щоб мінімізувати вплив дебажного вивода на роботу, використовуйте вищий бітрейт, наприклад 115200.

tss69 пише:

Тип float - під час випробувань приєдннував 1602, простіше(без перетворювання типів змінних) у використанні.

1602 - це алфавітно-цифровий дисплей? Не дуже зрозумілий його звʼязок з float. Ну то таке.

tss69
2024-12-10 01:15:35

У деяких прикладах при роботі з analogRead(A0) використовували delay(10) перед зчитуванням.
Використання  serial.println() потрібно було для контролю, у готовому приладі використовуватись не буде.
Тип float - під час випробувань приєдннував 1602, простіше(без перетворювання типів змінних) у використанні.

dimich
2024-12-10 00:36:39
tss69 пише:

Якщо замінити на delay(100), тоді затримка становить 10 секунд.

Навіщо там взагалі delay()? В 99.9% випадків, якщо в коді delay(), значить щось не так із кодом або алгоритмом в цілому.

dimich
2024-12-10 00:32:16
tss69 пише:

Код дуже простий.

Простий не значить правильний.

1. В приймачі ви намагаєтесь читати дані навіть коли їх нема. SofSoftwareSerial::read() при цьому повертає -1.
2. В передавачі затримка між посилками 10мс (+ якийсь час на виконання інших функцій). В приймачі затримка між спробами читання 200 мс. Приймач навіть теоретично не встигатиме читати всі відправлені передавачем дані. Навіщо взагалі в приймачі ця затримка 200 мс?
3. Кожну ітерацію в UART пишеться більше десятка байт ("Zadanie = " плюс саме значення та r). На 9600 бод їх передача займає  більше 10 мс. В передавачі з часом внутрішній буфер Serial заповнюється і Serial.print() блокує виконання поки буфер не звільниться.
До проблеми не відноситься, але все ж:
4. Навіщо там використання типу float?

Я би порадив для початку відлагодити комунікацію при безпосередньому TTL-зʼєднанні приймача з передавачем. Тільки після того як все працюватиме правильно, зʼєднувати по RS485.

tss69
2024-12-09 23:14:17

Знайшов причину затримки. У кінці коду приймача є команда затримки  delay(200). Після заміни на delay(10) затримка зникла. Якщо замінити на delay(100), тоді затримка становить 10 секунд. Таку затримку використовув коли для налагодження роботи підключав тимчасово дисплей 1602.

tss69
2024-12-09 20:58:11

Мені здається що затримка у приймачі. Як я описував, поведінка приймача така, що при зміні показів із затримкою в 5-10 секунд я фізично роз"єдную дроти, але приймач із затримкою потім показує принятий вірний результат.

tss69
2024-12-09 20:46:55

Я  це розумію, тому і питаю, можливо хтось мав досвід? Код дуже простий.
Приймач:

#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); 
}

dimich
2024-12-09 19:54:51

MAX485 не містить ніякої логіки і буферів. Якщо затримка 20 секунд, але дані таки приходять, то вони десь мають зберігатись. Це явно програмна помилка. Потрібно розуміти, на якій із сторін відбувається ця затримка. Не завадило би подивитись на код приймача і передавача.

tss69
2024-12-09 12:57:31

Соединил две ардуины через модули TTL-RS485 по стандартной схеме. Одна ардуина измеряет напряжение на переменном резисторе и передаёт на вторую. Передача только в одну сторону. Связь работает, но при изменении напряжения приёмник  принимает данные с задержкой 20 секунд. Приём и передачу контролирую в мониторе. Скорость связи менял 4800, 9600, 19200 - результат - задержка не изменилась. При изменении данных на передатчике через 10 секунд разрывал линию - на приёмнике с задержкой показания менялись! То-есть, приёмник принимает данные сразу, но "отдаёт" с задержкой 20 секунд. В приёмнике реализовано только приём данных и просмотр(контроль) в мониторе. Линия связи - витая пара, 40 м.

Підвал форуму