Как правильно считывать PWM?

bod
Offline
Зарегистрирован: 12.09.2011

Добрый день!

Требуется помощь! Не считываются показания цифрового компаса. 

Имеется:

Компас может отдавать значения по интерфейсам l2c и PWM.

Пытаюсь считать значения PWM.

Из документации:

The PWM signal is a pulse width modulated signal with the positive width of the pulse representing the angle.
The pulse width varies from 1mS (0° ) to 36.99mS (359.9° ) – in other words 100uS/° with a +1mS offset. The
signal goes low for 65mS between pulses, so the cycle time is 65mS + the pulse width - ie. 66ms-102ms. The
pulse is generated by a 16 bit timer in the processor giving a 1uS resolution, however I would not recommend
measuring this to anything better than 0.1° (10uS). Make sure you connect the I2C pins, SCL and SDA, to the
5v supply if you are using the PWM, as there are no pull-up resistors on these pins.

 

Компас подлключен на цифровой порт 3.  Проблема в том , что на вход всегда идет "1".

Проверял следующим кодом:

const int pwm_pin = 3;
int pwm_val = 0;
int pwm_val_t = 0;

void setup() {
Serial.begin(9600);
pinMode(pwm_pin, INPUT);
}

void loop() {
pwm_val=digitalRead(pwm_pin);
//if (pwm_val=0) pwm_val_t= pulseIn(pwm_pin, HIGH ) ;
if ( pwm_val=0) Serial.print(0); ;
//Serial.println();
//delay(200);
}

Что я не так делаю ? 

Zaliv
Offline
Зарегистрирован: 05.03.2011

 digitalRead всегда будет возвращать High или Low

Вам нужен похоже PulseIn чтобы считать длину сигнала

bod
Offline
Зарегистрирован: 12.09.2011

 Я и начал с  PulseIn, см. закомментаренный код. 

Мне кажется, что на вход всегда идет HIGH  , хотя LOW так же должен иди. 

step962
Offline
Зарегистрирован: 23.05.2011

А с подключением компаса к ардуине все в порядке? Что-то вроде этого?

(Схема расположена на http://www.robot-electronics.co.uk/htm/cmps2pwm.shtml)

Mogalkov
Offline
Зарегистрирован: 23.06.2011

Вообщето ШИМ считывать надо аналоговым портом. А учитывая вот это: Make sure you connect the I2C pins, SCL and SDA, это  Аналоговые 5 SCL и 4 SDA.

 

step962
Offline
Зарегистрирован: 23.05.2011

Mogalkov пишет:

Вообщето ШИМ считывать надо аналоговым портом. 

ШИМ-сигнал с пина 4 упоминаемого здесь компаса - это импульсы шириной 1-37 мс, выдаваемые с периодичностью 65 мс (www.robotstorehk.com/CMPS03_release.pdf). Задача именно для цифрового порта и таймера (вся соответствующая программная требуха зашита в логике PulseIn), а не для АЦП. Конечно, если по пути сигнала какую-нибудь интегрирующую цепочку соорудить, то можно и АЦП воспользоваться, но это как гланды через ж... вырезать.

А вот пины 2-3 (SDA-SCL) подтянуть к плюсу следует попробовать - где-то мне такой эскизик именно в контексте снятия PWM-сигнала с данного компаса попадался...

Кстати, и на приведенной мной схеме соответствующая рекомендация в виде текста имеется - "connect 2x47 Resistors from pins 2&3 to Vcc"

Mogalkov
Offline
Зарегистрирован: 23.06.2011

 Ну если импульсы надо, то можно через прерывания, тоесть импульс ХАЙЖ - прерывание запустилось и отсчитывает втемя через таймер в переменную пока импульс не ЛОУ. Но имхо I2C удобнее будет, к ней даже библиотека в стандартном комплекте дуины есть (ware). Резисторы от 4К7 от SCL и от SDA на +5 для подтяжки линий к ХАЙ, но по идее пулап резисторы должны уже стоять.

step962
Offline
Зарегистрирован: 23.05.2011

Mogalkov пишет:

... по идее пулап резисторы должны уже стоять.

По идее - может быть и да. По даташиту - нет:

"Make sure you connect the I2C pins, SCL and SDA, to the 5v
supply if you are using the PWM, as there are no pull-up resistors on these pin"

Цитата:
Но имхо I2C удобнее будет

Ну, топикстартер, похоже, выводы ардуины экономит...

Кстати, его что-то не слышно совсем.

Ау, ТС!!! Удалось добиться передачи информации по PWM-каналу или нет???

 

Starpom
Offline
Зарегистрирован: 06.03.2011

 А чем же PulseIn не подходит?, ждет начало сигнала и возвращает его длину в микросекундах, это ж то, что надо? или я что-то упускаю? ТС загадочно сказал, что у него закомменчено PulseIn, но почему закомменчено не ясно.

step962
Offline
Зарегистрирован: 23.05.2011

Starpom пишет:

ТС загадочно сказал, что у него закомменчено PulseIn, но почему закомменчено не ясно.

Как сказано в самом первом сообщении, его "проблема в том, что на вход всегда идет "1"". В таких условиях PulseIn просто не сработает - ведь на входе всегда HIGH.

bod
Offline
Зарегистрирован: 12.09.2011

 По поводу правильности подключения: шилд распаяный уже
http://www.inexglobal.com/products.php?type=addon&cat=app_sensors&model=...
трудно ошибиться, разъемы стандартные

По поводу подключения по I2C: у меня под рукой проводочков нужных нету :-(, да и хотелось разобраться с PWM/

 

Кроме варианта с кривыми руками , у меня еще есть следующие варианты:

  1. датчики от inex не подходят к ардуино
  2. IO Expansion Shield For Arduino(V5)(http://www.dfrobot.com/index.php?route=product/product&product_id=264) глючный

Грешу все же на IO Expansion Shield For Arduino(V5), т.к. если подключаю кнопку http://www.megachip.ru/item.php?item_id=2466000 то в нажатом состоянии с нее приходит сигнал "0", а в состоянии покоя "1".

bod
Offline
Зарегистрирован: 12.09.2011

step962 пишет:

Starpom пишет:

ТС загадочно сказал, что у него закомменчено PulseIn, но почему закомменчено не ясно.

Как сказано в самом первом сообщении, его "проблема в том, что на вход всегда идет "1"". В таких условиях PulseIn просто не сработает - ведь на входе всегда HIGH.

Все верно , т.к. PulseIn давал "0", я его закоммитил , что бы разобраться в чем дело.

step962
Offline
Зарегистрирован: 23.05.2011

 У вас соединены четыре платки в кучу - компас, переходная плата для компаса, IO Expansion Shield и Arduino?

И все без "проводочков"?

Хотелось бы взглянуть на фото собранной конструкции.

bod
Offline
Зарегистрирован: 12.09.2011

 

Zaliv
Offline
Зарегистрирован: 05.03.2011

 а на прямую без IO Expansion Shield пробовали подключать?

bod
Offline
Зарегистрирован: 12.09.2011

Zaliv пишет:

 а на прямую без IO Expansion Shield пробовали подключать?

не прбовал, видимо нужно это сделать, но нет под рукой проводов.

step962
Offline
Зарегистрирован: 23.05.2011

bod пишет:

Zaliv пишет:

 а на прямую без IO Expansion Shield пробовали подключать?

не прбовал, видимо нужно это сделать, но нет под рукой проводов.

Первое: паяльника тоже нет? Раздербанить какую-нибудь старую мышку или клаву, кусок витой пары, нарезать оттуда проводков, оголить/залудить концы - и можно прекрасно выполнять временную коммутацию через мама-разъемы ардуины и представленного на фотографии тройного шлейфика.

Второе: у вас светодиодик свободный найдется? Попробуйте подключать его к выводам компаса, переходной платки и т.д. и следить за изменением яркости свечения и частоты мигания (от 10 до 15 Гц) при повороте компаса.

Третье:судя по нижней фотографии на страничке компаса (www.inexglobal.com/products.php), Vcc  подается на дальний от кромки платки пин (зеленый проводок на вашей фотографии). А у IO-шилда Vcc находится ровно посередине (красный проводок). У вас есть схема разводки переходной платки? Уточните, пожалуйста, за что отвечает каждый из трех выводов PWM-разъема (на переходной платке). Ибо если мои подозрения верны, то на третий цифровой порт подается Vcc, то есть там всегда присутствует неизменный жирный HIGH - в полном соответствии с описываемыми симптомами. 

PS: кстати, и на компас в этом случае подается черти что, а не питание...

bod
Offline
Зарегистрирован: 12.09.2011

step962 пишет:

Первое: паяльника тоже нет? Раздербанить какую-нибудь старую мышку или клаву, кусок витой пары, нарезать оттуда проводков, оголить/залудить концы - и можно прекрасно выполнять временную коммутацию через мама-разъемы ардуины и представленного на фотографии тройного шлейфика.

Да. надо подключить на прямую.

step962 пишет:

Третье:судя по нижней фотографии на страничке компаса (www.inexglobal.com/products.php), Vcc подается на дальний от кромки платки пин (зеленый проводок на вашей фотографии). А у IO-шилда Vcc находится ровно посередине (красный проводок). У вас есть схема разводки переходной платки? Уточните, пожалуйста, за что отвечает каждый из трех выводов PWM-разъема (на переходной платке). Ибо если мои подозрения верны, то на третий цифровой порт подается Vcc, то есть там всегда присутствует неизменный жирный HIGH - в полном соответствии с описываемыми симптомами.

Зеленый проводок это +5V, как раз на фото видно , что дорожка идет к разъему , а рядом видно надпись на плате "5V"

Красный провод - это PWM(Pin 4 на плате компаса)

Черный GND

Я вот думаю , м.б. компасу питания не хватает ? С цифрового вывода 5V должно идти ?

step962
Offline
Зарегистрирован: 23.05.2011

 Ну вот, похоже, что-то проясняется. В стандартных шлейфах PWM-приводов (сервомашинки и прочая дребедень) линии располагаются в следующем порядке:

- масса (обычно черный)

- плюс (или Vcc) (обычно красный)

- сигнальная линия (белый или желтый)

Кстати, именно так эти выводы на используемой вами части IO Expansion Shield промаркированы (Gnd-Vcc-Signal или что-то там)

у вас же на переходной плате Gnd-Signal-Vcc - две линии в обратном порядке.

Так что - покопайте в эту сторону.

bod
Offline
Зарегистрирован: 12.09.2011

step962 пишет:

 Ну вот, похоже, что-то проясняется. В стандартных шлейфах PWM-приводов (сервомашинки и прочая дребедень) линии располагаются в следующем порядке:

- масса (обычно черный)

- плюс (или Vcc) (обычно красный)

- сигнальная линия (белый или желтый)

Кстати, именно так эти выводы на используемой вами части IO Expansion Shield промаркированы (Gnd-Vcc-Signal или что-то там)

у вас же на переходной плате Gnd-Signal-Vcc - две линии в обратном порядке.

Так что - покопайте в эту сторону.

Действительно. На стандартных разъемах от Inex, Signal и Vcc идут в другом порядке.

После того как сделал правильный порядок проводов все заработало.

step962, спасибо большое за помощь!
 

msd
Offline
Зарегистрирован: 02.10.2011

 if ( pwm_val=0)

эквивалентно 

 if ( false )

надо написать if ( pwm_val == 0)

stepan_sotnikov
Offline
Зарегистрирован: 06.04.2019

Есть вопрос так же по ШИМ. Arduino Una
pulseln() не предлагать. 
У меня на порты приходят 5 каналов с ШИМ.
самый быстрый я повесил на 2 пин, остальные повесил на 3 пин. с 4 датчиков приходит сигнал в порт, и через диоды от всех на 3 пин. И по прерыванию опрашиваю порт. Вопрос, в ниже я привожу свой код и там два варианта. Опроса один закоменчен.
И тот и тот работает, но мне не нравится как работают. Мне кажется я, не очень красиво написал их. На прерывание на 3 пин не смотрите. Но если есть советы я выслушаю. На втором порту нужна полная характеристика, на 3 только частота.
 


​void setup() {
  Serial.begin(230400);
  initPins(); //функция инициализации Pin
  cli();//отключаем прерывание

  //настройка таймера 2
  TCCR2A = 0; //обнулили
  TCCR2B = 0; //обнулили
  TIMSK2 = (1 << TOIE1);
  TCCR2B |= (1 << CS10); //настроили без деления 255*6.25е-8 сек.
  
  attachInterrupt(digitalPinToInterrupt(rotSensor_All), isr_wheel, RISING);// актевирует срабатывания функции rotationSenaor на пине 2 изменение с 0, на 1
  attachInterrupt(digitalPinToInterrupt(PWRDAT_Pin), isr_ppm, CHANGE);// актевирует срабатывания функции PWRDAT_H на пине 3 изменение с 0, на 1
  
  sei();//разрешили прерывание
  PPM_status = digitalRead(PWRDAT_Pin); // текущее состояние берём из состояния пина
}

// Проверка 
void isr_ppm() {
  if (PPM_status & 1) { // 
    PWR_Pulse = PWR_TIMER; // запоминаем время между импульсами
    PWR_TIMER = 0; // обнуляем таймер    
  } else {              // 
    PWR_Duty = PWR_TIMER; //запоминаем время продолжительности импульса  
  }
  
  PPM_status ^ 1;       // 0b00000001     // применяем побитовый XOR, 1 такт 
}

/* void PWRDAT_H () {//обработка начала импульса ШИМ
  PWR_Pulse = PWR_TIMER; // запоминаем время между импульсами
  PWR_TIMER = 0; // обнуляем таймер
  attachInterrupt(1, PWRDAT_L, FALLING);// активирует срабатывания функции PWRDAT_L на пине 3 изменение с 0, на 1
}
void PWRDAT_L () {//обработка спада импульса ШИМ
  PWR_Duty = PWR_TIMER; //запоминаем время продолжительности импульса
  attachInterrupt(1, PWRDAT_H, RISING);// активирует срабатывания функции PWRDAT_H на пине 3 изменение с 1, на 0
} */

void isr_wheel () {//функция работы с датчиками  по прерыванию на пине 2 (прерывание 0 )
  DataRotSensor = PIND;
  switch (DataRotSensor & (1 << N)) {
    case 7: tWbl = rotSensor_back_left_Timer; rotSensor_back_left_Timer = 0;
      break;
    case 6: tWbr = rotSensor_back_right_Timer; rotSensor_back_right_Timer = 0;
      break;
    case 5: tWfl = rotSensor_front_left_Timer; rotSensor_front_left_Timer = 0;
      break;
    case 4: tWfr = rotSensor_front_right_Timer; rotSensor_front_right_Timer = 0;
      break;  
  }
}

ISR (TIMER2_OVF_vect) { //по переполнению таймера срабатывает прерывание каждые 15 мкс
  rotSensor_back_left_Timer++ ;//таймер датчика вращения
  rotSensor_back_right_Timer++;//таймер датчика вращения 
  rotSensor_front_left_Timer++;//таймер датчика вращения 
  rotSensor_front_right_Timer++;//таймер датчика вращения 
  PWR_TIMER++;//таймер длительность сигнала ШИМ
}