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

Создаем свой блок. Вопросы, помощь знатоков.
Ответить
Ingwar
Полковник
Сообщения: 1928
Зарегистрирован: 28 окт 2015, 22:47
Откуда: Ленобласть
Имя: Игорь
Поблагодарили: 2 раза

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

Сообщение 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).
Что я делаю не так?
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Люди в своем большинстве живо интересуются всем на свете, за исключением того, что действительно стоит знать.
aidar_i
Полковник
Сообщения: 3357
Зарегистрирован: 24 дек 2016, 16:55
Откуда: Уфа
Имя: Айдар
Благодарил (а): 13 раз
Поблагодарили: 100 раз
Контактная информация:

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

Сообщение aidar_i »

Ingwar писал(а): 07 дек 2021, 21:00 Что я делаю не так?
Я бы посоветовал обратиться в форум ардуино.ру. Сам часто туда обращаюсь, помогают. Правда нужно там вопросы задавать конкретно с выкладыванием кода.
Если просто помогите, пошлют подальше, это не наш форум. Меня пока не послали, хотя и подкалывали. Лучше не пишите что делаете блок для флпрог.
Ingwar
Полковник
Сообщения: 1928
Зарегистрирован: 28 окт 2015, 22:47
Откуда: Ленобласть
Имя: Игорь
Поблагодарили: 2 раза

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

Сообщение Ingwar »

Для понимания картины:
Используя смещение в "+" на генераторе видим
[spoiler]
с5.png
[/spoiler]
Убираем смещение в и получаем такие гуляющие значения...
[spoiler]
с4.png
[/spoiler]
и
[spoiler]
с3.png
[/spoiler]

Отправлено спустя 9 минут 16 секунд:
И дело не в том, что отрицательные Uвх предельно -0,3Uпитания (на графике размах 0,05В). Подключаю тензодатчик (мост) и в одну сторону нормально (положительные значения), а в другую - каша...
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Люди в своем большинстве живо интересуются всем на свете, за исключением того, что действительно стоит знать.
Аватара пользователя
Sancho
Полковник
Сообщения: 4066
Зарегистрирован: 25 дек 2015, 17:32
Откуда: Ярославль.
Имя: Александр
Поблагодарили: 5 раз
Контактная информация:

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

Сообщение 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; // собираем три байта данных с АЦП
Но тоже при сборке возможно будет ругаться.
мой ник в нете и почте omelchuk890, если что. запомните на всякий. многие знают номер тлф.
Аватара пользователя
Dryundel
Полковник
Сообщения: 2422
Зарегистрирован: 22 май 2017, 23:15
Откуда: Ярославль
Имя: Андрей
Поблагодарили: 28 раз

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

Сообщение Dryundel »

Ingwar писал(а): 07 дек 2021, 21:00 Что я делаю не так?
Не особо силен в тонкостях битовых операций, но возможно проблема в сдвиге байта больше чем на 15. Вроде как требуется преобразовывать тип данных, в UL, т.к. сдвиг выполняется в ячейке int.
Смотри информацию здесь (глава Битовый сдвиг):
https://alexgyver.ru/lessons/bitmath/
Ingwar
Полковник
Сообщения: 1928
Зарегистрирован: 28 окт 2015, 22:47
Откуда: Ленобласть
Имя: Игорь
Поблагодарили: 2 раза

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

Сообщение 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]
Т. е. вернулись к результату как и у меня..
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Люди в своем большинстве живо интересуются всем на свете, за исключением того, что действительно стоит знать.
Аватара пользователя
Sancho
Полковник
Сообщения: 4066
Зарегистрирован: 25 дек 2015, 17:32
Откуда: Ярославль.
Имя: Александр
Поблагодарили: 5 раз
Контактная информация:

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

Сообщение 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;
мой ник в нете и почте omelchuk890, если что. запомните на всякий. многие знают номер тлф.
Ingwar
Полковник
Сообщения: 1928
Зарегистрирован: 28 окт 2015, 22:47
Откуда: Ленобласть
Имя: Игорь
Поблагодарили: 2 раза

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

Сообщение 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]
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Люди в своем большинстве живо интересуются всем на свете, за исключением того, что действительно стоит знать.
Аватара пользователя
Sancho
Полковник
Сообщения: 4066
Зарегистрирован: 25 дек 2015, 17:32
Откуда: Ярославль.
Имя: Александр
Поблагодарили: 5 раз
Контактная информация:

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

Сообщение 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.
Из даташита
У вас нет необходимых прав для просмотра вложений в этом сообщении.
мой ник в нете и почте omelchuk890, если что. запомните на всякий. многие знают номер тлф.
Ingwar
Полковник
Сообщения: 1928
Зарегистрирован: 28 окт 2015, 22:47
Откуда: Ленобласть
Имя: Игорь
Поблагодарили: 2 раза

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

Сообщение Ingwar »

Sancho писал(а): 08 дек 2021, 13:06Из даташита
Условия соблюдены, но результат увы...
Смотрел тут один ролик из профильного канала по электронике и автор сравнивая продукцию TI и AD отмечал проблемы/трудности как раз с TI.
Вот теперь думаю, может присмотреться к AD?
Люди в своем большинстве живо интересуются всем на свете, за исключением того, что действительно стоит знать.
Аватара пользователя
Dryundel
Полковник
Сообщения: 2422
Зарегистрирован: 22 май 2017, 23:15
Откуда: Ярославль
Имя: Андрей
Поблагодарили: 28 раз

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

Сообщение Dryundel »

Ingwar писал(а): 08 дек 2021, 12:46 Я пробовал все промежуточные переменные объявлять как unsigned long int и как long int, получается "...вид сбоку" )
Почитай статью. Надо непосредственно при сдвиге ставить UL.
Ingwar
Полковник
Сообщения: 1928
Зарегистрирован: 28 окт 2015, 22:47
Откуда: Ленобласть
Имя: Игорь
Поблагодарили: 2 раза

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

Сообщение 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;
тоже не дал положительных изменений.
В общем нахер эту "борьбу". Если и буду юзать этот АЦП, то только со смещением или сажать отрицательный вход на "землю".
Люди в своем большинстве живо интересуются всем на свете, за исключением того, что действительно стоит знать.
Аватара пользователя
Sancho
Полковник
Сообщения: 4066
Зарегистрирован: 25 дек 2015, 17:32
Откуда: Ярославль.
Имя: Александр
Поблагодарили: 5 раз
Контактная информация:

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

Сообщение Sancho »

Ingwar писал(а): 07 дек 2021, 23:42 Убираем смещение в и получаем такие гуляющие значения...
Прочитал тему о плоттере.
А если попробовать выводить как unsigned ?
Будет, конечно, выглядеть не красиво, но, возможно, появится понятие, откуда периодические засады со значащим битом.
мой ник в нете и почте omelchuk890, если что. запомните на всякий. многие знают номер тлф.
Ingwar
Полковник
Сообщения: 1928
Зарегистрирован: 28 окт 2015, 22:47
Откуда: Ленобласть
Имя: Игорь
Поблагодарили: 2 раза

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

Сообщение 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 точно равен расчетной задержке.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Люди в своем большинстве живо интересуются всем на свете, за исключением того, что действительно стоит знать.
Аватара пользователя
Sancho
Полковник
Сообщения: 4066
Зарегистрирован: 25 дек 2015, 17:32
Откуда: Ярославль.
Имя: Александр
Поблагодарили: 5 раз
Контактная информация:

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

Сообщение 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 Можно конечно самому нужный счетчик завернуть в ПБ или скорректировать код, но на эмоциях пока плюнул. Отойду, может и попробую.
Согласен!
мой ник в нете и почте omelchuk890, если что. запомните на всякий. многие знают номер тлф.
Ingwar
Полковник
Сообщения: 1928
Зарегистрирован: 28 окт 2015, 22:47
Откуда: Ленобласть
Имя: Игорь
Поблагодарили: 2 раза

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

Сообщение Ingwar »

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

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

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 4 гостя