я не знаю, что он там напереводил, разбираем по правилам русского языка, мы же русские люди:
Аналоговый выход *2 - 4-20ма (точка)
ДАЛЕЕ ПАРАМЕТРЫ АНАЛОГОВОГО ВЫХОДА 4 - 20 МА:
сопротивление нагрузки …
я не знаю, что он там напереводил, разбираем по правилам русского языка, мы же русские люди:
Аналоговый выход *2 - 4-20ма (точка)
ДАЛЕЕ ПАРАМЕТРЫ АНАЛОГОВОГО ВЫХОДА 4 - 20 МА:
сопротивление нагрузки …
Сорян. В походных условиях, поспешил, поверил) по ходу не прокатило)
судя из даташита это я заблуждался, датчик имеет три режима выхода:
Если у датчика есть “выход по АЦП”, так не нужно морочить себе и окружающим голову, а нужно снимать с датчика показания прямо в цифре.
тут я оговорился, конечно для АЦП
PS русский языка такой неоднозначный
Пока такое решение от аналога, чтобы тему подвести ближе к концу.
Подключение датчика:
Скетч ардуино:
#include <Wire.h>
#include <Adafruit_ADS1X15.h>
Adafruit_ADS1115 ads;
void setup() {
Serial.begin(115200); // Инициализация последовательного порта на 115200 бод
Wire.begin(); // Запускаем библиотеку Wire для I2C
ads.begin(); // Инициализация ADS1115
ads.setGain(GAIN_ONE); // Установка усиления
ads.setDataRate(RATE_ADS1115_860SPS); // Установка скорости выборки 860 SPS
}
void loop() {
Serial.write(0xFF); // Контрольная точка
int16_t adc = ads.readADC_SingleEnded(0); // Читаем значение с первого канала (A0)
// Передача данных через UART
uint8_t highByte = (adc >> 8) & 0xFF; // Старший байт
uint8_t lowByte = adc & 0xFF; // Младший байт
// Преобразуем 16-разрядное значение в два байта
Serial.write(highByte); // Отправляем старший байт
Serial.write(lowByte); // Отправляем младший байт
// добавляем в двух-байтовом формате мсек
unsigned long ms = millis(); // Текущие миллисекунды
// Выделяем старший (high) и младший (low) байты
uint8_t highByte2 = (ms >> 8) & 0xFF; // Старший байт
uint8_t lowByte2 = ms & 0xFF; // Младший байт
// Передача байтов
Serial.write(highByte2); // Старший байт
Serial.write(lowByte2); // Младший байт
// delay(1); // Задержка. при необходимости
}
Главное замечание по коду скетча: все же надо заголовок (проверочный код) ставить 2-х байтовым иначе возникают “проскоки”.
Добавил может временно миллисекунды. Скорость вывода в порт при этом можно сказать не меняется, но интереснее иметь время. Если убрать работу ADS скорость возрастает в разы.
Главная часть работы программы на VisualBasic.net:
Private Sub serialPort_DataReceived(sender As Object, e As IO.Ports.SerialDataReceivedEventArgs) Handles serialPort.DataReceived
If receivingData Then
Dim bytesToRead As Integer = serialPort.BytesToRead ' количество байт в порту
serialPort.Read(buffer, kol, bytesToRead) ' считываем по байтово и заполняем массив buffer байтами
kol = kol + bytesToRead
Label1.Text = kol
End If
End Sub
Результаты обработки затухающего колебания по количеству точек:
В принципе амплитуду видно явным образом. При особом желании, которого у меня нет, можно перейти на другой АЦП приведенный выше.
Забыл добавить. По фреймам не стал выводить, контрольную сумму тоже
Спасибо всем
поясните эту фразу. Если убрать что?
Из скетча убрать получение данных. Проверил, что именно “тормозит” кроме меня
Если бы вы перевели АДС в continuous mode, а не запускали каждый раз конверсию в блокирующем режиме - у вас все работало бы быстрее.
Лучше покажите этот же график, где по Х нанесено время. Это даст возможность оценить, какая у вас реальная скорость чтения АЦП.
Добавка - нашел эти данные в спойлере, примерно 400 SPS вместо 860-ти. Переходите в continuous mode, скорость должна вырасти.
Если правильно понял, что за режим, то не ускорилось. Или неверно истолковал (поместил в цикл в скетче, не стал пока убирать время)
void loop() {
while(true){
Serial.write(0xFF); // Контрольные точки
Serial.write(0xFF); // Контрольные точки
int16_t adc = ads.readADC_SingleEnded(0); // Читаем значение с первого канала (A0) - ЗДЕСЬ ТОРМОЗИТ
// Передача данных через UART
uint8_t highByte = (adc >> 8) & 0xFF; // Старший байт
uint8_t lowByte = adc & 0xFF; // Младший байт
// Преобразуем 16-разрядное значение в два байта
Serial.write(highByte); // Отправляем старший байт
Serial.write(lowByte); // Отправляем младший байт
// добавляем в двух-байтовом формате мсек
unsigned long ms = millis(); // Текущие миллисекунды
// Выделяем старший (high) и младший (low) байты
uint8_t highByte2 = (ms >> 8) & 0xFF; // старший байт
uint8_t lowByte2 = ms & 0xFF; // младший байт
// Передача байтов
Serial.write(highByte2); // Сначала высший байт
Serial.write(lowByte2); // Затем низший байт
}
// delay(1); // Задержка. при необходимости
}
Похоже нет. Я, честно говоря, вообще не вижу что вы изменили по сравнению с прошлым вариантом.
В библиотеке есть пример использования непрерывного режима, посмотрите. Смысл в том, что вам не нужно пинать АДС для выполнения каждого замера, вы запускаете непрерывное преобразование в фоне и потом просто читаете результаты.
Можно и без библиотеки, там два байта конфигурации просто установить и потом соответственно читать, пишешь в нулевой регистр и читаешь пока не отдаст два байта, будет быстрее (может быть)
по крайней мере тогда у него печать результатов будет идти параллельно с измерением нового значения, а не последовательно, как сейчас
Не могу понять почему не работает с проверкой получения новых данных через new_data
#include <Adafruit_ADS1X15.h>
Adafruit_ADS1115 ads;
#ifndef IRAM_ATTR
#define IRAM_ATTR
#endif
constexpr int READY_PIN = 0; //пробовал разные пины
volatile bool new_data = false;
void IRAM_ATTR NewDataReadyISR() {
new_data = true;
}
void setup(void) {
Serial.begin(115200); //скорость передачи
ads.setGain(GAIN_ONE); // Установка усиления (можно изменить в зависимости от вашего датчика)
ads.setDataRate(RATE_ADS1115_860SPS); // Установка скорости выборки 860 SPS
if (!ads.begin()) {
while (1)
;
} //ждем подключения
pinMode(READY_PIN, INPUT);
// With default COMP_POL=0, get a rising edge every time a new sample is ready.
attachInterrupt(digitalPinToInterrupt(READY_PIN), NewDataReadyISR, RISING);
// Старт в continuous режиме
ads.startADCReading(ADS1X15_REG_CONFIG_MUX_SINGLE_0, true);
}
void loop(void) {
if (!new_data) {
return;
}
Serial.write(0xFF); // Контрольные точки
Serial.write(0xFF); // Контрольные точки
//Передача измерения в двухбайтовом формате
int16_t adc = ads.getLastConversionResults(); //Снимаем точки в continuous режиме
// Передача данных через UART
uint8_t highByte = (adc >> 8) & 0xFF; // Старший байт
uint8_t lowByte = adc & 0xFF; // Младший байт
// Преобразуем 16-разрядное значение в два байта
Serial.write(highByte); // Отправляем старший байт
Serial.write(lowByte); // Отправляем младший байт
//Передача мсек в двухбайтовом формате
unsigned long ms = millis(); // Текущие миллисекунды
// Выделяем старший (high) и младший (low) байты
uint8_t highByte2 = (ms >> 8) & 0xFF; // старший байт
uint8_t lowByte2 = ms & 0xFF; // младший байт
// Передача байтов
Serial.write(highByte2); // Сначала высший байт
Serial.write(lowByte2); // Затем низший байт
new_data = false;
}
Если через delay, то данные нормально идут с интервалом 1,5 мсек, но понятно, что раз в n-мсек повторное значение, т.к. в буфере данные не успевают обновиться
#include <Adafruit_ADS1X15.h>
Adafruit_ADS1115 ads;
void setup(void) {
Serial.begin(115200); //скорость передачи
ads.setGain(GAIN_ONE); // Установка усиления (можно изменить в зависимости от вашего датчика)
ads.setDataRate(RATE_ADS1115_860SPS); // Установка скорости выборки 860 SPS
if (!ads.begin()) {
while (1)
;
} //ждем подключения
// Старт в continuous режиме
ads.startADCReading(ADS1X15_REG_CONFIG_MUX_SINGLE_0, true);
}
void loop(void) {
Serial.write(0xFF); // Контрольные точки
Serial.write(0xFF); // Контрольные точки
//Передача измерения в двухбайтовом формате
int16_t adc = ads.getLastConversionResults(); //Снимаем точки в continuous режиме
// Передача данных через UART
uint8_t highByte = (adc >> 8) & 0xFF; // Старший байт
uint8_t lowByte = adc & 0xFF; // Младший байт
// Преобразуем 16-разрядное значение в два байта
Serial.write(highByte); // Отправляем старший байт
Serial.write(lowByte); // Отправляем младший байт
//Передача мсек в двухбайтовом формате
unsigned long ms = millis(); // Текущие миллисекунды
// Выделяем старший (high) и младший (low) байты
uint8_t highByte2 = (ms >> 8) & 0xFF; // старший байт
uint8_t lowByte2 = ms & 0xFF; // младший байт
// Передача байтов
Serial.write(highByte2); // Сначала высший байт
Serial.write(lowByte2); // Затем низший байт
delay(1); // Задержка необходима
}
Может потому что
Надо не наобум “пробовать”, а знать, какой пин подходит для этого. Прерывания работают не на всех пинах.
Напомните, какой контроллер у вас? Нано?
Да, нано. ADS подключен к А4 (SDA) и А5 (SCL). На ADS к A0 датчик
На Нано для прерывания можно использовать пины 2 и 3.
А у вас в коде пин 0 - это вообще грубейшая ошибка. Мало того что на этом пине не работают прерывания - пин 0(а также пин1) заняты соединением с ПК. Если вы повесите что-то на эти пины - у вас перестанет работать Serial
Да, PIN0 просто уже пробовал в скетче ради интереса, т.к. не нашел описания, но не по железу подключал.
То есть здесь указать 3? Это не работало (понимаю, что явно здесь неверно что-то)
constexpr int READY_PIN = 0;
А по железу на ардуино надо что-то подключение менять?
Или где можно это почитать…?
По-моему нет.
Насколько я вижу, вы постарались повторить пример из библиотеки. На первый взгляд все верно.