Отрицательные значения

Создаем свой блок. Вопросы, помощь знатоков.
Ответить
Ingwar
Полковник
Сообщения: 1929
Зарегистрирован: 28.10.2015{, 22:47}
Репутация: 223
Откуда: Ленобласть
Имя: Игорь

Отрицательные значения

#1

Сообщение Ingwar » 07.12.2021{, 21:00}

Делаю ПБ для АЦП ADS1251.
Почти "победил". Положительные значения считываю без проблем, а вот с отрицательными бяда...
Протокол довольно простой
СпойлерПоказать
Безымянный.png
Опуская настройки таймингов, функция чтения выглядит так.

Код: Выделить всё

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).
Что я делаю не так?
Люди в своем большинстве живо интересуются всем на свете, за исключением того, что действительно стоит знать.

aidar_i
Полковник
Сообщения: 3125
Зарегистрирован: 24.12.2016{, 16:55}
Репутация: 676
Откуда: Уфа
Имя: Айдар
Контактная информация:

Отрицательные значения

#2

Сообщение aidar_i » 07.12.2021{, 21:49}

Ingwar писал(а):
07.12.2021{, 21:00}
Что я делаю не так?
Я бы посоветовал обратиться в форум ардуино.ру. Сам часто туда обращаюсь, помогают. Правда нужно там вопросы задавать конкретно с выкладыванием кода.
Если просто помогите, пошлют подальше, это не наш форум. Меня пока не послали, хотя и подкалывали. Лучше не пишите что делаете блок для флпрог.

Ingwar
Полковник
Сообщения: 1929
Зарегистрирован: 28.10.2015{, 22:47}
Репутация: 223
Откуда: Ленобласть
Имя: Игорь

Отрицательные значения

#3

Сообщение Ingwar » 07.12.2021{, 23:33}

Для понимания картины:
Используя смещение в "+" на генераторе видим
СпойлерПоказать
с5.png
Убираем смещение в и получаем такие гуляющие значения...
СпойлерПоказать
с4.png
и
СпойлерПоказать
с3.png
Отправлено спустя 9 минут 16 секунд:
И дело не в том, что отрицательные Uвх предельно -0,3Uпитания (на графике размах 0,05В). Подключаю тензодатчик (мост) и в одну сторону нормально (положительные значения), а в другую - каша...
Люди в своем большинстве живо интересуются всем на свете, за исключением того, что действительно стоит знать.

Аватара пользователя
Sancho
Полковник
Сообщения: 4066
Зарегистрирован: 25.12.2015{, 17:32}
Репутация: 590
Откуда: Ярославль.
Имя: Александр
Контактная информация:

Отрицательные значения

#4

Сообщение Sancho » 08.12.2021{, 09:39}

Ingwar, Нужно попробовать просто

Код: Выделить всё

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; // собираем три байта данных с АЦП
Но тоже при сборке возможно будет ругаться.
мой ник в нете и почте omelchuk890, если что. запомните на всякий. многие знают номер тлф.

Аватара пользователя
Dryundel
Полковник
Сообщения: 2401
Зарегистрирован: 22.05.2017{, 23:15}
Репутация: 783
Откуда: Ярославль
Имя: Андрей
Контактная информация:

Отрицательные значения

#5

Сообщение Dryundel » 08.12.2021{, 11:50}

Ingwar писал(а):
07.12.2021{, 21:00}
Что я делаю не так?
Не особо силен в тонкостях битовых операций, но возможно проблема в сдвиге байта больше чем на 15. Вроде как требуется преобразовывать тип данных, в UL, т.к. сдвиг выполняется в ячейке int.
Смотри информацию здесь (глава Битовый сдвиг):
https://alexgyver.ru/lessons/bitmath/

Ingwar
Полковник
Сообщения: 1929
Зарегистрирован: 28.10.2015{, 22:47}
Репутация: 223
Откуда: Ленобласть
Имя: Игорь

Отрицательные значения

#6

Сообщение Ingwar » 08.12.2021{, 12:02}

Sancho писал(а):
08.12.2021{, 09:44}
Ingwar, Нужно попробовать просто
Скомпилилось без проблем с типом всех промежуточных uint32_t, стало так
СпойлерПоказать
Безымянный1.png
Если типы указаны как в первом посте, вот так
СпойлерПоказать
Безымянный.png
Отправлено спустя 4 минуты 38 секунд:
Dryundel писал(а):
08.12.2021{, 11:50}
Вроде как требуется преобразовывать тип данных, в UL
Я пробовал все промежуточные переменные объявлять как unsigned long int и как long int, получается "...вид сбоку" )

Отправлено спустя 4 минуты 18 секунд:
Sancho писал(а):
08.12.2021{, 09:44}
Нужно попробовать просто
Такой вид, если все объявить как long int
СпойлерПоказать
Безымянный.png
Т. е. вернулись к результату как и у меня..
Люди в своем большинстве живо интересуются всем на свете, за исключением того, что действительно стоит знать.

Аватара пользователя
Sancho
Полковник
Сообщения: 4066
Зарегистрирован: 25.12.2015{, 17:32}
Репутация: 590
Откуда: Ярославль.
Имя: Александр
Контактная информация:

Отрицательные значения

#7

Сообщение Sancho » 08.12.2021{, 12:35}

Ingwar, 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;
мой ник в нете и почте omelchuk890, если что. запомните на всякий. многие знают номер тлф.

Ingwar
Полковник
Сообщения: 1929
Зарегистрирован: 28.10.2015{, 22:47}
Репутация: 223
Откуда: Ленобласть
Имя: Игорь

Отрицательные значения

#8

Сообщение Ingwar » 08.12.2021{, 12:46}

Sancho писал(а):
08.12.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; // собираем три байта данных с АЦП
    	
}
Вот его интерфейс
СпойлерПоказать
Безымянный.png
Люди в своем большинстве живо интересуются всем на свете, за исключением того, что действительно стоит знать.

Аватара пользователя
Sancho
Полковник
Сообщения: 4066
Зарегистрирован: 25.12.2015{, 17:32}
Репутация: 590
Откуда: Ярославль.
Имя: Александр
Контактная информация:

Отрицательные значения

#9

Сообщение Sancho » 08.12.2021{, 12:56}

Для пробы понимания правильности обработки результата преобразования знакового 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
2021-12-08_12-52-25.png (12.35 КБ) 703 просмотра
Все значения после 800000h будут уменьшать значение отрицательного числа, т.е. FFFFFC даст -4

Отправлено спустя 10 минут 23 секунды:
Ingwar писал(а):
08.12.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.
Из даташита
мой ник в нете и почте omelchuk890, если что. запомните на всякий. многие знают номер тлф.

Ingwar
Полковник
Сообщения: 1929
Зарегистрирован: 28.10.2015{, 22:47}
Репутация: 223
Откуда: Ленобласть
Имя: Игорь

Отрицательные значения

#10

Сообщение Ingwar » 08.12.2021{, 13:14}

Sancho писал(а):
08.12.2021{, 13:06}
Из даташита
Условия соблюдены, но результат увы...
Смотрел тут один ролик из профильного канала по электронике и автор сравнивая продукцию TI и AD отмечал проблемы/трудности как раз с TI.
Вот теперь думаю, может присмотреться к AD?
Люди в своем большинстве живо интересуются всем на свете, за исключением того, что действительно стоит знать.

Аватара пользователя
Dryundel
Полковник
Сообщения: 2401
Зарегистрирован: 22.05.2017{, 23:15}
Репутация: 783
Откуда: Ярославль
Имя: Андрей
Контактная информация:

Отрицательные значения

#11

Сообщение Dryundel » 08.12.2021{, 17:20}

Ingwar писал(а):
08.12.2021{, 12:46}
Я пробовал все промежуточные переменные объявлять как unsigned long int и как long int, получается "...вид сбоку" )
Почитай статью. Надо непосредственно при сдвиге ставить UL.

Ingwar
Полковник
Сообщения: 1929
Зарегистрирован: 28.10.2015{, 22:47}
Репутация: 223
Откуда: Ленобласть
Имя: Игорь

Отрицательные значения

#12

Сообщение Ingwar » 08.12.2021{, 19:24}

Dryundel писал(а):
08.12.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;
тоже не дал положительных изменений.
В общем нахер эту "борьбу". Если и буду юзать этот АЦП, то только со смещением или сажать отрицательный вход на "землю".
Люди в своем большинстве живо интересуются всем на свете, за исключением того, что действительно стоит знать.

Аватара пользователя
Sancho
Полковник
Сообщения: 4066
Зарегистрирован: 25.12.2015{, 17:32}
Репутация: 590
Откуда: Ярославль.
Имя: Александр
Контактная информация:

Отрицательные значения

#13

Сообщение Sancho » 10.12.2021{, 10:53}

Ingwar писал(а):
07.12.2021{, 23:42}
Убираем смещение в и получаем такие гуляющие значения...
Прочитал тему о плоттере.
А если попробовать выводить как unsigned ?
Будет, конечно, выглядеть не красиво, но, возможно, появится понятие, откуда периодические засады со значащим битом.
мой ник в нете и почте omelchuk890, если что. запомните на всякий. многие знают номер тлф.

Ingwar
Полковник
Сообщения: 1929
Зарегистрирован: 28.10.2015{, 22:47}
Репутация: 223
Откуда: Ленобласть
Имя: Игорь

Отрицательные значения

#14

Сообщение Ingwar » 10.12.2021{, 14:14}

Sancho, я теперь тупо не верю ни выводу в порт ни плоттеру. Попытался сымитировать вывод в порт 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 бит.
СпойлерПоказать
IMG_20211210_135854.jpg
Художник я еще тот. Это синусоида с обрезанными и смещенными в противоположный знак верхушками по значениям -32768 и +32767

Отправлено спустя 3 минуты 22 секунды:
Да, еще, смотрел осликом DOUT - DRDY Mode точно равен расчетной задержке.
Люди в своем большинстве живо интересуются всем на свете, за исключением того, что действительно стоит знать.

Аватара пользователя
Sancho
Полковник
Сообщения: 4066
Зарегистрирован: 25.12.2015{, 17:32}
Репутация: 590
Откуда: Ярославль.
Имя: Александр
Контактная информация:

Отрицательные значения

#15

Сообщение Sancho » 10.12.2021{, 15:15}

Ingwar писал(а):
10.12.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.12.2021{, 14:17}
Можно конечно самому нужный счетчик завернуть в ПБ или скорректировать код, но на эмоциях пока плюнул. Отойду, может и попробую.
Согласен!
мой ник в нете и почте omelchuk890, если что. запомните на всякий. многие знают номер тлф.

Ingwar
Полковник
Сообщения: 1929
Зарегистрирован: 28.10.2015{, 22:47}
Репутация: 223
Откуда: Ленобласть
Имя: Игорь

Отрицательные значения

#16

Сообщение Ingwar » 10.12.2021{, 17:24}

Sancho писал(а):
10.12.2021{, 15:33}
Код очень даже рабочий для приёма 24 бит в 32. ИМХО.
Спасибо, расту над собой )).
Люди в своем большинстве живо интересуются всем на свете, за исключением того, что действительно стоит знать.

Ответить

Вернуться в «Разработка пользовательских блоков»