Страница 1 из 1
Отрицательные значения
Добавлено: 07 дек 2021, 21:00
Ingwar
Делаю ПБ для АЦП
ADS1251.
Почти "победил". Положительные значения считываю без проблем, а вот с отрицательными бяда...
Протокол довольно простой
[spoiler]
Безымянный.png
[/spoiler]
Опуская настройки таймингов, функция чтения выглядит так.
Код: Выделить всё
ads_output = 0;
byte1=SPI.transfer(0x00); // прием старшего байта
byte1=byte1<<16; // двигаем старший байт влево на два байта
byte2=SPI.transfer(0x00); // прием среднего байта
byte2=byte2<<8; // двигаем средний байт влево на один байт
byte3=SPI.transfer(0x00); // прием младшего байта
ads_output =byte1|byte2|byte3; // собираем три байта данных с АЦП
Типы объявленных переменных (пробовал все в знаковые, результат не изменен)
Код: Выделить всё
long int byte1;
unsigned int byte2;
unsigned int byte3;
long int ads_output= 0;
Где то находил способ записи 24 битного знакового числа в 32 битную переменную и пробовал добавлять строки
Код: Выделить всё
if((ads_output&0x800000)==0x800000)
{
ads_output |= 0xff000000;
}
Увы, без изменений.
SPI_MODE по умолчанию (должен быть SPI_MODE0).
Что я делаю не так?
Отрицательные значения
Добавлено: 07 дек 2021, 21:49
aidar_i
Ingwar писал(а): 07 дек 2021, 21:00
Что я делаю не так?
Я бы посоветовал обратиться в форум ардуино.ру. Сам часто туда обращаюсь, помогают. Правда нужно там вопросы задавать конкретно с выкладыванием кода.
Если просто помогите, пошлют подальше, это не наш форум. Меня пока не послали, хотя и подкалывали. Лучше не пишите что делаете блок для флпрог.
Отрицательные значения
Добавлено: 07 дек 2021, 23:42
Ingwar
Для понимания картины:
Используя смещение в "+" на генераторе видим
[spoiler]
с5.png
[/spoiler]
Убираем смещение в и получаем такие гуляющие значения...
[spoiler]
с4.png
[/spoiler]
и
[spoiler]
с3.png
[/spoiler]
Отправлено спустя 9 минут 16 секунд:
И дело не в том, что отрицательные Uвх предельно -0,3Uпитания (на графике размах 0,05В). Подключаю тензодатчик (мост) и в одну сторону нормально (положительные значения), а в другую - каша...
Отрицательные значения
Добавлено: 08 дек 2021, 09:44
Sancho
[ref]Ingwar[/ref], Нужно попробовать просто
Код: Выделить всё
ads_output = 0;
byte1=SPI.transfer(0x00); // прием старшего байта
byte2=SPI.transfer(0x00); // прием среднего байта
byte3=SPI.transfer(0x00); // прием младшего байта
ads_output =((byte1 << 24)|(byte2 << 16)|(byte3<< 8)) >> 8; // собираем три байта данных с АЦП
Отправлено спустя 4 минуты 42 секунды:
Возможно, не прокатит из-за типов, я не вижу Ваших объявлений, тогда так
ads_output =int32_t((uint32_t(byte1) << 24)|(uint32_t(byte2) << 16)|(uint32_t(byte3) << 8)) >> 8; // собираем три байта данных с АЦП
Но тоже при сборке возможно будет ругаться.
Отрицательные значения
Добавлено: 08 дек 2021, 11:50
Dryundel
Ingwar писал(а): 07 дек 2021, 21:00
Что я делаю не так?
Не особо силен в тонкостях битовых операций, но возможно проблема в сдвиге байта больше чем на 15. Вроде как требуется преобразовывать тип данных, в UL, т.к. сдвиг выполняется в ячейке int.
Смотри информацию здесь (глава Битовый сдвиг):
https://alexgyver.ru/lessons/bitmath/
Отрицательные значения
Добавлено: 08 дек 2021, 12:11
Ingwar
Sancho писал(а): 08 дек 2021, 09:44
Ingwar, Нужно попробовать просто
Скомпилилось без проблем с типом всех промежуточных uint32_t, стало так
[spoiler]
Безымянный1.png
[/spoiler]
Если типы указаны как в первом посте, вот так
[spoiler]
Безымянный.png
[/spoiler]
Отправлено спустя 4 минуты 38 секунд:
Dryundel писал(а): 08 дек 2021, 11:50
Вроде как требуется преобразовывать тип данных, в UL
Я пробовал все промежуточные переменные объявлять как
unsigned long int и как
long int, получается "...вид сбоку" )
Отправлено спустя 4 минуты 18 секунд:
Sancho писал(а): 08 дек 2021, 09:44
Нужно попробовать просто
Такой вид, если все объявить как
long int
[spoiler]
Безымянный.png
[/spoiler]
Т. е. вернулись к результату как и у меня..
Отрицательные значения
Добавлено: 08 дек 2021, 12:38
Sancho
[ref]Ingwar[/ref], byte 1 2 3 объявить байтами.
Отправлено спустя 3 минуты 8 секунд:
ads_output = 0;
byte1=SPI.transfer(0x00); // прием старшего байта
byte2=SPI.transfer(0x00); // прием среднего байта
byte3=SPI.transfer(0x00); // прием младшего байтаads_output =int32_t((uint32_t(byte1) << 24)|(uint32_t(byte2) << 16)|(uint32_t(byte3) << 8)) >> 8;
Отрицательные значения
Добавлено: 08 дек 2021, 12:46
Ingwar
Sancho писал(а): 08 дек 2021, 12:35
Ingwar, byte 1 2 3 объявить байтами.
Не взлетело...
Я все больше склоняюсь, что в этом АЦП просто нельзя, чтобы отрицательный вход был больше положительного.
Вот прекрасно работающий с отрицательными числами пример из ПБ для другого АЦП ADS1271
Код: Выделить всё
#include <SPI.h>
long dat_;
long int dat_1;
int dat_2;
int dat_3;
void setup()
{
SPI.begin ();
pinMode(10, INPUT); //DRDY
attachInterrupt (10 , SCLK_ADS1271, FALLING);
}
void loop()
{
//Плата:1
}
void SCLK_ADS1271()
{
dat_ = 0L;
dat_1=SPI.transfer(0x01); // прием старшего байта
dat_1=dat_1<<16; // двигаем старший байт влево на два байта
dat_2=SPI.transfer(0x01); // прием среднего байта
dat_2=dat_2<<8; // двигаем средний байт влево на один байт
dat_3=SPI.transfer(0x01); // прием младшего байта
dat_=dat_1|dat_2|dat_3; // собираем три байта данных с АЦП
}
Вот его интерфейс
[spoiler]
Безымянный.png
[/spoiler]
Отрицательные значения
Добавлено: 08 дек 2021, 13:06
Sancho
Для пробы понимания правильности обработки результата преобразования знакового 24 битного в знаковое 32-х битное
byte1 = 0x80;
byte2 = 0;
byte3 = 0;
ads_output =int32_t((uint32_t(byte1) << 24)|(uint32_t(byte2) << 16)|(uint32_t(byte3) << 8)) >> 8;
согласно
2021-12-08_12-52-25.png
Все значения после 800000h будут уменьшать значение отрицательного числа, т.е. FFFFFC даст -4
Отправлено спустя 10 минут 23 секунды:
Ingwar писал(а): 08 дек 2021, 12:46
Я все больше склоняюсь, что в этом АЦП просто нельзя, чтобы отрицательный вход был больше положительного.
The bipolar input voltage range is from –4.096
to +4.096V, when the reference input voltage equals +4.096V.
The bipolar range is with respect to –VIN, and not with respect
to GND.
....
Each of the differential inputs of the ADS1251 must stay
between –0.3V and VDD.
Из даташита
Отрицательные значения
Добавлено: 08 дек 2021, 13:14
Ingwar
Sancho писал(а): 08 дек 2021, 13:06Из даташита
Условия соблюдены, но результат увы...
Смотрел тут один ролик из профильного канала по электронике и автор сравнивая продукцию TI и AD отмечал проблемы/трудности как раз с TI.
Вот теперь думаю, может присмотреться к AD?
Отрицательные значения
Добавлено: 08 дек 2021, 17:20
Dryundel
Ingwar писал(а): 08 дек 2021, 12:46
Я пробовал все промежуточные переменные объявлять как unsigned long int и как long int, получается "...вид сбоку" )
Почитай статью. Надо непосредственно при сдвиге ставить UL.
Отрицательные значения
Добавлено: 08 дек 2021, 19:24
Ingwar
Dryundel писал(а): 08 дек 2021, 17:20
Почитай статью. Надо непосредственно при сдвиге ставить UL.
Читал. Про знаки в статье не нашел/проглядел. Но я еще нахожусь на уровне - угадал все буквы, но не смог назвать слово.
Вариант предложенный Александром,
Код: Выделить всё
ads_output = 0;
byte1=SPI.transfer(0x00); // прием старшего байта
byte2=SPI.transfer(0x00); // прием среднего байта
byte3=SPI.transfer(0x00); // прием младшего байта
ads_output =int32_t((uint32_t(byte1) << 24)|(uint32_t(byte2) << 16)|(uint32_t(byte3) << 8)) >> 8;
тоже не дал положительных изменений.
В общем нахер эту "борьбу". Если и буду юзать этот АЦП, то только со смещением или сажать отрицательный вход на "землю".
Отрицательные значения
Добавлено: 10 дек 2021, 10:53
Sancho
Ingwar писал(а): 07 дек 2021, 23:42
Убираем смещение в и получаем такие гуляющие значения...
Прочитал тему о плоттере.
А если попробовать выводить как unsigned ?
Будет, конечно, выглядеть не красиво, но, возможно, появится понятие, откуда периодические засады со значащим битом.
Отрицательные значения
Добавлено: 10 дек 2021, 14:17
Ingwar
[ref=#ff8000]Sancho[/ref], я теперь тупо не верю ни выводу в порт ни плоттеру. Попытался сымитировать вывод в порт 32ух битной знаковой "пилы" через счетчик, но обломался - в штатном только int или unsigned long. Можно конечно самому нужный счетчик завернуть в ПБ или скорректировать код, но на эмоциях пока плюнул. Отойду, может и попробую.
Меня еще повеселила картинка с такого кода одного из экспериментов (ads_ знаковая 32)
Код: Выделить всё
int i = 23;
int k = 0;
while(i >= 0)
{
D13_High;
if (D12_Read)
{
k = 1;
}
else
{
k = 0;
}
bitWrite(ads_, i, k);
D13_Low;
i--;
}
Я понимаю, что пишу только 24 бита в 32, но результат... Скрин не делал, нарисовал от руки. Размах вверх/вниз ровно 16 бит.
[spoiler]
IMG_20211210_135854.jpg
[/spoiler]
Художник я еще тот. Это синусоида с обрезанными и смещенными в противоположный знак верхушками по значениям -32768 и +32767
Отправлено спустя 3 минуты 22 секунды:
Да, еще, смотрел осликом DOUT - DRDY Mode точно равен расчетной задержке.
Отрицательные значения
Добавлено: 10 дек 2021, 15:33
Sancho
Ingwar писал(а): 10 дек 2021, 14:17
Меня еще повеселила картинка с такого кода одного из экспериментов (ads_ знаковая 32)
Код очень даже рабочий для приёма 24 бит в 32. ИМХО.
Можно уменьшить, но для понимания самое то.
int i = 23;
int k = 0;
ads_ = 0; // в зависимости от задачи
while(i >= 0)
{
D13_High;
bitWrite(ads_, i, D12_Read );
//вариант 2 -> if (D12_Read){bitWrite(ads_, i, 1 );} // нужно обязательно делать ads_ = 0; + неравномерные такт. импульсы
D13_Low;
i--;
}
Отправлено спустя 18 минут 35 секунд:
Ingwar писал(а): 10 дек 2021, 14:17
Можно конечно самому нужный счетчик завернуть в ПБ или скорректировать код, но на эмоциях пока плюнул. Отойду, может и попробую.
Согласен!
Отрицательные значения
Добавлено: 10 дек 2021, 17:24
Ingwar
Sancho писал(а): 10 дек 2021, 15:33
Код очень даже рабочий для приёма 24 бит в 32. ИМХО.
Спасибо, расту над собой )).