Работа с битовым представлением

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013
я получаю от восьмиканального устройства состояние его каналов в виде восьми нулей/единиц:
  • deviceState: 01111100 - контакт на 1-м канале разомкнут, LED на 4-м канале включен (остальное аналогично)
  • deviceState: 01111101 - контакт на 1-м канале замкнут, LED на 4-м канале включен
  • deviceState: 01110101 - контакт на 1-м канале замкнут, LED на 4-м канале выключен
Как мне выделить (узнать) из этого только, к примеру, состояние контакта на 1-м канале - 0111110x, независимо от остальных циферок?
Т.е. в идеале получить что-то вроде boolean state1ch = true/false.
Наложение маски boolean state1ch  = deviceState & 00000001; не срабатывает (точнее, выполняет не то, что в моем представлении ожидалось).
Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015
if(bitRead(B01111100, 3))
  Serial.println("LED 4 включен");

 

Datak
Offline
Зарегистрирован: 09.10.2014

Tomasina пишет:

 
Наложение маски boolean state1ch  = deviceState & 00000001; не срабатывает (точнее, выполняет не то, что в моем представлении ожидалось).

Странно. Вообще-то должно быть именно то. А полный текст можно?

Только не забывайте  b  добавлять к маске - для единицы оно может и так сойдёт, а для других разрядов вряд ли. :)

А ешё так не делайте - 













boolean state5ch = deviceState & 0b00010000;

if( state5ch == TRUE )
{
   .....
   .....
}

- скорее всего не сработает, хотя и кажется на первый взгляд, что всё правильно.

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

без b как раз коряво работает.

Penni, спасибо.

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

Datak пишет:

А ешё так не делайте - 

boolean state5ch = deviceState & 0b00010000;
if( state5ch == TRUE )
{
   .....
}

- скорее всего не сработает, хотя и кажется на первый взгляд, что всё правильно.

хм, выглядит-то всё цивильно :) Область видимости?

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

пардон, но в постановке задачи неоднозначность.....

какие биты отвечают за канал ? какие - за вкл/выкл ?

 

или чёта пропустил :(

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

если канал работает на вход (чтение состояния), то 0 - контакт разомкнут, 1 - замкнут
если канал работает на выход (питание нагрузки), то 1 - есть 5В, 0 - нет напряжения.

Нумерация справа налево.

В данном случае это не важно - с этими заморочками мне все понятно.

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

byte deviceState: - можно узнать какой бит за что отвечает ?

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

Tomasina пишет:

если канал работает на вход (чтение состояния), то 0 - контакт разомкнут, 1 - замкнут
если канал работает на выход (питание нагрузки), то 1 - есть 5В, 0 - нет напряжения.

Нумерация справа налево.

В данном случае это не важно - с этими заморочками мне все понятно.

извините, но это - бла..........

см. #7

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

тогда мне непонятен ваш вопрос.

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

вы получили от устройства ( 8-ми канального ) байт состояния....

как его ( байта ) состояние битов интерпретировать ?

 

если канал работает на вход (чтение состояния), то 0 - контакт разомкнут, 1 - замкнут
если канал работает на выход (питание нагрузки), то 1 - есть 5В, 0 - нет напряжения.

Нумерация справа налево.

В данном случае это не важно - с этими заморочками мне все понятно.

 

как это понимать ?

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

Как мне выделить (узнать) из этого только, к примеру, состояние контакта на 1-м канале - 0111110x, независимо от остальных циферок?

моя думал про вас - что это легко.... щас - прикалываетесь, видимо :(

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

моя твоя не понимай...

получаю в переменной deviceState значение 01110101.

  • 1-й канал = 1-й байт: 1 - контакт замкнут
  • 2-й канал = 2-й байт: 0 - контакт разомкнут
  • 3-й канал = 3-й байт: 1 - контакт замкнут
  • 4-й канал = 4-й байт: 0 - LED №1 выключен (на нем 0 Вольт)
  • 5-й канал = 5-й байт: 1 - LED №2 включен (на нем 5 Вольт)
  • 6-й канал = 6-й байт: 1 - LED №3 включен
  • 7-й канал = 7-й байт: 1 - LED №4 включен
  • 8-й канал = 8-й байт: 0 - LED №5 выключен

Что сидит на каждом канале - геркон или LED - мне известно.

В вопросе мне надо было узнать состояние конкретного канала, имея весь набор данных. Как это сделать - теперь мне понятно. :)

Сам канал может быть и входом и выходом:
Each of 8 PIO is opendrain and can be use as output or as input. No configuration is needed to use PIO as output or as input.
- to use pin as output, write value in PIO register
- to use pin as input, simply read value.

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

после #12 - всё понятно :)

Как это сделать - теперь мне понятно. :)

типеричя - ещё понятнее :)

Datak
Offline
Зарегистрирован: 09.10.2014

Tomasina пишет:

Datak пишет:











boolean state5ch = deviceState & 0b00010000;
if( state5ch == TRUE )
{
   .....
}

хм, выглядит-то всё цивильно :) Область видимости?

Не, не в этом дело. Просто компиляторы часто (если не всегда) не поддерживают настоящий тип boolean или bool, а используют вместо него обычный int  или byte. В результате boolean-переменная может принимать не 2 значения, как хотелось бы, а намного больше.

Поэтому в выражении  boolean state5ch = deviceState & 0b00010000;  переменной  state5ch  присваиваются не логические 0 или 1, а байтовые 0b00000000 или 0b0010000;
А значение true, для компилятора, при этом определено всё же как обычная единица.

Получается, что условие  if( state5ch == true )  будет работать не так, как условие  if( state5ch != false )

if( 0b0010000 == 1 )  не выполняется, а  if( 0b0010000 != 0 )  выполняется.

Такие вот грабли. :)

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

if( state5ch == TRUE )   ->    if( state5ch > 0 )

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

if( state5ch > 0 ) - > if( state5ch )

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

это уже слишком просто :)

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

Чем проще решение, тем оно непонятнее новичкам. Классика :)
Думаю, что компилятор любое из этих выражений все равно приведёт к наиболее оптимальному, т.е. размер прошивки не изменится.

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012
if( state5ch == TRUE ) -> if( state5ch )

Самое оптимальное и логичное.

Сравнение на >0 - выдуманное и нелогичное, некорректное, поскольку deviceState изначально беззнаковое по смыслу. Уж тогда лучше сравнивать на неравенство нулю.

А есть еще вариант:

boolean state5ch = ( deviceState & 0b00010000 ? TRUE : FALSE );

Более читабельно и понятно.

PS По опыту, сравнивать что либо с true/TRUE не стОит, наступали на эти грабли в реальных проектах.