bit_is_set Всегда true для PORT D4 (Leonardo)

catfishkin
Offline
Зарегистрирован: 12.06.2016

Привет,

есть скетч который раньше работал на pro mini, сейчас понадоболось это все перенести на Leonardo.

Проблема в том, что Леонардо, все время думает что заданный мной порт, на прием данных, эти данные получает всегда.

код:

//задем порт с которым будем работать

#define DATAIN_DDR DDRD

#define DATAIN_PORT PORTD

#define DATAIN_PIN PIND

#define DATAIN 4

// принемаем на веру
//http://myrobot.ru/articles/p_avrgcc_ver.php

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

//проверка стотояния порта
#define INPUT_IS_SET   (bit_is_set(DATAIN_PIN, DATAIN))
#define INPUT_IS_CLEAR (bit_is_clear(DATAIN_PIN, DATAIN))

//устанавливаем нуль на нашем датаИН порте
  cbi(DATAIN_DDR,  DATAIN);
  cbi(DATAIN_PORT, DATAIN);

// гдето в нутри loop
  if ( INPUT_IS_SET ) {
    Serial.println("E");
}
 
Результат:
всегда печатаеться Е, тойсть получаеться что на порт приходят данные, хотя он в воздухе.
если мультиметром я меряю напряжение между этим портом и GND то в проверку я не захожу, и все вроди ок.
 
Это в чем проблемма ?
Или все правильно работает просто я не разобрался в схеме и в коде полностью?
 
 
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, это Вы самти разбирайтесь, раз не хотите скетч показывать.

В каком месте расположены строки 26-27? Вызываются ли они? В каком месте "где-то внутри loop"? А что там ещё есть "где-то внутри loop"? Нет ли там, например,  sbi(DATAIN_PORT, DATAIN);?

На все перечисленные вопросы ответ один - ХЗ!

Ну и на вопрос топика ответ такой же!

catfishkin
Offline
Зарегистрирован: 12.06.2016

Сколько раз было такое что пишиш вопрос а потом буквально пол часа и ответ нашел.

https://youtu.be/EkDvpXziBC0?list=PLygUYOEl6XIpFyd-1n6O2RYCqLisJl-W6&t=437

Вот тут все понятно ) нужно просто было выставить резистор.

Видать в Arduino Pro mini это както автоматически сделано.

 

catfishkin
Offline
Зарегистрирован: 12.06.2016

Хотя нет, все ровно не понятно. То работаето то нет. 

В общем вот код:

void setup() {
  pinMode(10, INPUT);
  digitalWrite(10, HIGH);
}

void loop() {
  if (PINB & (1<<PINB6))
  {
    Serial.println("E");
  }
}

Устанавливаю портB6 это пин 10 для Leonardo на прием и ожидаю что принта Е не будет, так как на этото порт ничего не подключено, ровным счетом как и на другие пины тожо. Сейчас в консоль все время сыпет "Е", что не так ?

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

catfishkin, вы подтянули вход к единице, команда читает единицу. Ваше условие срабатывает. Всё так.

catfishkin
Offline
Зарегистрирован: 12.06.2016

Хм, ну ОК. А как тогда нужно написать, чтобы установить пин на чтение, и ждать момента когда туда что-то прийдет?

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Смотря что вы ждёте. На единицу больше не среагирует, можно только ноль ловить. if (PINB&(1<<6)==0) ...

catfishkin
Offline
Зарегистрирован: 12.06.2016

Если я правильно понимаю, то пока этот порт висит в воздухе, там будет 1,

если я подключу к нему свою перефирию ))), то на порту появится лигический 0, и программа будет рабоать как мне надо. Мне надо так: этот пин должен быть своего рода снифером для устройсва которое умеет выдатьвсть импульмы, +5 лог 1, ну нуль есть нуль )

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

catfishkin пишет:

Если я правильно понимаю, то пока этот порт висит в воздухе, там будет 1,

Нет. Если пин висит в воздухе, то там будут "помехи". Это состояние Hi-Z (высокоомное, высокоимпедансное). В этом случае пин настраивается на вход, но не включается подтяжка к 1. А с вклюяённой подтяжкой к 1, пин уже не висит в воздухе - там будет лог. 1, пока на этот пин не придёт сигнал лог. 0  и не пересилит единицу, после чего с пина считается лог. 0

catfishkin пишет:

если я подключу к нему свою перефирию ))), то на порту появится лигический 0

Только после того, как ваша переферия подаст лог. 0

catfishkin пишет:

, и программа будет рабоать как мне надо. Мне надо так: этот пин должен быть своего рода снифером для устройсва которое умеет выдатьвсть импульмы, +5 лог 1, ну нуль есть нуль )

Всё верно, если у переферии двухтактный выход (только лог.1 и лог. 0). Если будет Hi-Z со стороны переферии, то ардуина считает лог. 1 (потому что включена подтяжка к 1 при отсутствии сигнала).

catfishkin
Offline
Зарегистрирован: 12.06.2016

Jeka_M пишет:

Только после того, как ваша переферия подаст лог. 0

Спасибо, все подключил все работает ).

Думал что опять чтото не так, а получается, что, когда в Леонардо ставиш порт на выход, то тот порт который до этого стоял на вход, поднимаеться до логической 1. Это особенность Леонардо.

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

catfishkin пишет:

Думал что опять чтото не так, а получается, что, когда в Леонардо ставиш порт на выход, то тот порт который до этого стоял на вход, поднимаеться до логической 1. Это особенность Леонардо.

Это не особенность Леонардо, так и должно быть. Если пин сначала был сконфигурирован на вход и включена подтяжка:

pinMode(10, INPUT); // режим входа
digitalWrite(10, HIGH); // включаем подтяжку к "1"

а потом перевести его в режим выхода: pinMode(10, OUTPUT), но без выключения подтяжки: digitalWrite(10, LOW), то естественно на этом пине сразу появится лог "1".  Просто в МК AVR подтяжка в режиме входа включается точно так же, как и подаётся лог "1" в режиме выхода. Разница только в том, какой режим в этот момент выставлен - вход или выход. Это скорее особенность МК AVR.

То есть, если Вам надо вход с подтяжкой до лог "1" переключить на выход с лог "0", то делается так:

digitalWrite(10, LOW); // сначала выключаем подтяжку
pinMode(10, OUTPUT); // а потом переводим в режим выхода

 

catfishkin
Offline
Зарегистрирован: 12.06.2016

Нет, я вот что имел введу:

  pinMode( 8, INPUT_PULLUP ); 
  pinMode( 9, OUTPUT);           

Если я пишу так то, на пин 8 всегда 5В, если не инциализировать 9 пин то все ок.

Где-то читал, что леонардо умет только с 2х пин писать Tx0, Tx1, если Digital установлены на прием. 

Или я чтото путаю?

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

catfishkin пишет:

Нет, я вот что имел введу:

  pinMode(8, INPUT_PULLUP ); 
  pinMode(9, OUTPUT);           

Если я пишу так то, на пин 8 всегда 5В, если не инциализировать 9 пин то все ок.

pinMode(8, INPUT_PULLUP ) - это тоже самое, что и:

pinMode(8, INPUT);
digitalWrite(8, HIGH);

Там будет 5В потому, что этот пин подключён через внутренний подтягивающий резистор к 5В. Но эти 5В "пересилит" поданный на пин 0 (он же GND). Короткого замыкания не происходит, потому что ток ограничивает резистор. А слабые помехи не могут пересилить эти 5В через резистор, поэтому всегда читается лог 1.  Таков смысл подтяжки.

Если подключить светодиод катодом к земле (GND), а анодом к входу с включённой подтяжкой - то светодиод будет слегка светиться за счёт прохождения небольшого тока через подтягивающий резистор. 

Инициализация девятого пина никак не должна влиять на состояние восьмого.

catfishkin пишет:

Где-то читал, что леонардо умет только с 2х пин писать Tx0, Tx1, если Digital установлены на прием. 

Или я чтото путаю?

Вот тут не совсем понял, что Вы имеете в виду.

Если Вам нужно использовать Serial, то пины TX/RX вообще трогать и конфигурировать не надо. Делаете только инициализацию Serial.begin(). Пины сами сконфигурируются так, как им надо.

Или Вы про ножки T0 (D6) и T1 (D12), которые входы для аппаратных таймеров? Тогда да, другие выбрать нельзя. А если программно импульсы считывать (поллингом) - то можно с любых.

catfishkin
Offline
Зарегистрирован: 12.06.2016

Jeka_M пишет:

Если Вам нужно использовать Serial, то пины TX/RX вообще трогать и конфигурировать не надо. Делаете только инициализацию Serial.begin(). Пины сами сконфигурируются так, как им надо.

Или Вы про ножки T0 (D6) и T1 (D12), которые входы для аппаратных таймеров? Тогда да, другие выбрать нельзя. А если программно импульсы считывать (поллингом) - то можно с любых.

нет я вот спутал вот с чем:

 На Arduino Leonardo некоторые выводы не поддерживают прерывания, возникающие при
 изменении уровня сигнала. Поэтому, на этой плате в качестве вывода RX могут
 использоваться только следующие выводы: 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI).
 
Да мне как раз и надо импульсы считать (IE-BUS) :), пока достаточно просто читать,
может в будущем научусь и писать, если понадобиться, тогда дейстаитьльно Serial1 узать и головы не морочить.
 
Что каксается ноги 9, пока сам не могу понять, может как-то перефирия действует на 8 ногу
при изменении статуса 9. Сегодня после работы надо будет дома еще потестировать,
а то в обед сколько время было, попробовал, может чтото упустил.
 
D12 - что-то на Arduino Pro Micro не нахожу )) это случаем не 9 нога )))))))))))
 
Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

catfishkin пишет:

нет я вот спутал вот с чем:

 На Arduino Leonardo некоторые выводы не поддерживают прерывания, возникающие при
 изменении уровня сигнала. Поэтому, на этой плате в качестве вывода RX могут
 использоваться только следующие выводы: 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI).

А, дак это Вы про SoftwareSerial... Он нужен только, если нет возможности подключится к аппаратному Serial (пины TX/RX) или нужен ещё один последовательный порт.

catfishkin пишет:

D12 - что-то на Arduino Pro Micro не нахожу )) это случаем не 9 нога )))))))))))

Вы про входы аппаратных таймеров? На Pro Micro от SparkFun похоже, что нога D12 (на которой вход таймера T1) попросту не выведена... Встречаются и другие варианты Pro Micro, на которых она выведена.