Почему на контакте 6 моего Adafruit Feather RP2040 не подается высокий уровень, когда я об этом прошу?

У меня есть Adafruit Feather RP2040 (контакты), подключенный через контакт 6 к реле. Код (ниже) запускает реле, когда отдельный датчик цвета возвращает сигнал «достаточно». красные значения.

Датчик цвета работает (подтверждено отчетами серийной печати); встроенный светодиод (подключенный внутри к контакту 13) загорается тогда, когда должен; но я не получаю напряжения на контакте 6, когда должно. Напряжение проверяю стандартным мультиметром. Если я перенесу соединительный провод с контакта 6 на контакт 13, я получу напряжение (и реле сработает). Почему на контакт 6 не поступает напряжение? Что еще я могу сделать, чтобы диагностировать проблему?

Версии программного обеспечения:

  • Arduino.CC IDE v2.2.1 (последняя версия)
  • Менеджер платы Arduino IDE: добавлен https://github.com/earlephilhower/arduino-pico, версия 3.6. 0 (последний)
  • Библиотека Adafruit APDS9960 из https://github.com/adafruit/Adafruit_APDS9960, версия 1.2.3, выпущенная 30 января в этом году. Согласно https://github.com/adafruit/Adafruit_APDS9960/tags, 12 мая выпущена версия 1.2.4. , но поскольку это всего лишь код датчика освещенности, который ведет себя правильно, я не думаю, что проблема здесь.

Код:

// скопировано & изменено из источника по адресу:
// https://github.com/adafruit/Adafruit_APDS9960/blob/master/examples/color_sensor/color_sensor.ino

#include "Adafruit_APDS9960.h"
Adafruit_APDS9960 apds;

// штифт на перье, который мы используем для связи с реле
#define PIN_TO_RELAY 6

#define BUCKET_FULL_RED 50

void setup() {
  // включаем последовательную связь
  Serial.begin(115200);

  // пытаемся запустить датчик цвета
  if(!apds.begin()) {
    Serial.println("failed to initialize device! Please check your wiring.");
  }
  else {
    // Предполагаем успех
    // Serial.println("Устройство инициализировано!");

    // нам нужны значения цвета
    apds.enableColor(true);
  }

  // определяем вывод реле как ВЫХОДНОЙ вывод
  pinMode(PIN_TO_RELAY, OUTPUT);
  // начинаем с реле "open" АКА не запускает насос
  digitalWrite(PIN_TO_RELAY, LOW);

  //используем встроенный светодиод как внешний сигнал для "накачки";
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  // создаем несколько переменных для хранения данных о цвете; не используется, кроме «красного»
  uint16_t red, green, blue, clear;

  // для проверки состояния контакта реле
  int relay_pin_state = 0;

  // для дополнительной печати
  int debug = 1;
  
  // ждем, пока данные цвета будут готовы
  while (!apds.colorDataReady()) {
    delay(5);
  }
  // получаем свежие данные; нас волнует только красный цвет, но мы должны прочитать их все
  apds.getColorData(&red, &green, &blue, &clear);

  if (debug) {
    Serial.print("current red value is:"); Serial.println(red);
  }

  if (debug > 2) {
    relay_pin_state = digitalRead(PIN_TO_RELAY);
    if (relay_pin_state == HIGH) {
      Serial.println("steadystate: Relay pin is HIGH / enabled");
    } else {
      Serial.println("steadystate: Relay pin is LOW / disabled");
    }
  }

  if (red > BUCKET_FULL_RED) {
    if (debug) {
      Serial.println("start the pump (for 5 sec)");
    }
    
    // зажигаем встроенный светодиод
    digitalWrite(LED_BUILTIN, HIGH);
    // "закрыть" реле для включения насоса
    digitalWrite(PIN_TO_RELAY, HIGH);

    if (debug > 2) {
      relay_pin_state = digitalRead(PIN_TO_RELAY);
      if (relay_pin_state == HIGH) {
        Serial.println("pumping: Relay pin is HIGH / enabled");
      } else {
        Serial.println("pumping: Relay pin is LOW / disabled");
      }
    }

    // ждем некоторое время, пока насос сделает свою работу
    // 5 секунд в мс; TODO: в итоге около 4 минут
    delay(5 * 1000);
    
    if (debug) {
      Serial.println("stop the pump");
    }

    // выключаем встроенный светодиод
    digitalWrite(LED_BUILTIN, LOW);
    // "открыть" реле для отключения насоса
    digitalWrite(PIN_TO_RELAY, LOW);
  }
  // нет необходимости быстро переключаться; подождите 1 секунду в мс
  delay(1 * 1000);
}

Я только что еще раз внимательно посмотрел на страницу с распиновками и был удивлен, увидев отверстие с надписью «6». на передней панели имеется надпись «GP08». на задней панели, что соответствует «GPIO8»; в https://learn.adafruit.com/assets/107203. Интересно, отправляю ли я "D4" вывод ВЫСОКИЙ («GPIO6») вместо того, который я ожидал.

, 👍3

Обсуждение

Прежде чем углубляться в отладку кода, убедитесь, что все вспомогательное программное обеспечение и библиотеки обновлены. У меня были ранние версии библиотек Adafruit, которые работали просто ужасно., @st2000

вероятно, потому, что вы не говорите ему подниматься на высокий уровень... установите все контакты на высокий уровень... если контакт становится высоким, то установите 1/2 контактов на низкий уровень... и т. д., @jsotola

@st2000 хорошая выноска; Я отредактировал сообщение, включив в него известные мне версии программного обеспечения, которые могут повлиять на это. Если есть что-то еще, что я могу проверить, пожалуйста, дайте мне знать. Спасибо!, @Jeff Schaller

@jsotola Я в замешательстве; Я специально приказываю контакту 6 перейти на «ВЫСОКИЙ» уровень с помощью строки digitalWrite(PIN_TO_RELAY, HIGH);, а затем сообщаю ему перейти на «НИЗКИЙ» уровень позже. Окружающие линии для LED_BUILTIN работают правильно, поэтому я *предположил*, что команда вывода 6 на высокий уровень будет работать таким же образом. Возможно, нет?, @Jeff Schaller

Более пристальный взгляд на схему распиновки показывает, что «контакт 6» может не быть тем, что помечен как «6»; будет повторное тестирование с контактом 8., @Jeff Schaller

... и все. Что вы все думаете? Закрыть как опечатку для контакта «6» и контакта GPIO 8 или разместить автоответ в качестве предупреждения для других?, @Jeff Schaller

Я не знаю, что вам следует делать, но это повторяющаяся ситуация с платами, где есть D-номера и настоящие правильные номера GPIO, [особенно на платах ESP8266](https://arduinoprosto.ru/q/ 94659/70020). [Этот файл](https://github.com/adafruit/circuitpython/blob/16c8c9a/ports/raspberrypi/boards/adafruit_feather_rp2040/pins.c#L19-L24) может показаться вам поучительным. В материале Филхауэра может (а может и не быть) карта где-то от D# до GPIO#., @timemage

Было бы неплохо, если бы вы разместили самоответ, желательно с фотографией, чтобы было понятно, как вас смутило то, что «8» на печатной плате выглядит как «6»., @Nick Gammon


2 ответа


Лучший ответ:

3

Оказывается, я ввёл вас в заблуждение своим невежеством. Я считал само собой разумеющимся, что вещь с надписью «6» на передней панели на самом деле был Pin 6, но это не так:

перо с контактом "6" в кружке

Действительно, если я переверну это, это будет "GP08":

обратная сторона пера с тем же местом, обозначенным "GP08"

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

Пользователь timemage указал на подобную путаницу в недавнем сообщении: D1 mini ESP8266 нет звука в динамике, поскольку трафаретная наклейка на передней панели платы не соответствует фактическому номеру контакта. Они также указывают на файл, на который я бы никогда не наткнулся, но демонстрируют следующее сопоставление: https://github.com/adafruit/circuitpython/blob/16c8c9a739cfe0db2c712696eb340de2d7944d41/ports/raspberrypi/boards/adafruit_feather_rp2040/pins.c#L24, а именно:

 { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO2) },
{ MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO3) },
{ MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO7) },
{ MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO8) }, /* прямо здесь */
{ MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) },
{ MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO10) },

Описание распиновки, на мой взгляд, по-прежнему содержит некоторую вводящую в заблуждение информацию:

D6/GP08 — контакт 6 цифрового ввода-вывода. Это также SPI1 MISO, UART1 TX, I2C0 SDA и PWM4 A.

Вот, мне кажется, это место до сих пор называется «пин 6».

,

Разве у Arduino нет определений для контактов? Например, вы не можете просто ввести «D6» (или «GPIO_8»)? Я знаю, что раньше было такое..., @Daniël van den Berg

Для меня это совершенно новый мир, Даниэль! Я чувствую, что медленно изучаю «язык» вещей и становлюсь новичком — я просто принимал вещи за чистую монету. Похоже, что есть перевод, который происходит с термином MP_QSTR_D6, но я пока не знаю, во что это превращается, и очевидно ли вообще, что это относится к «тому, что на лицевой стороне доски написано 6». ., @Jeff Schaller

@DaniëlvandenBerg, вы связались с несвязанной платформой, @Juraj

@Юрай, упс... Похоже, библиотека, упомянутая adafruit, действительно включает определения контактов: https://github.com/earlephilhower/arduino-pico/blob/db7ba160ae238534ac1d89381748db3ed3b6dfe9/variants/generic/common.h и https:// github.com/earlephilhower/arduino-pico/blob/db7ba160ae238534ac1d89381748db3ed3b6dfe9/variants/adafruit_feather/pins_arduino.h , но тогда это все равно D8, а не D6. Я ожидал, что D6 обратится к шелковому экрану заранее и переведет на правильный номер GPIO... Странно..., @Daniël van den Berg


2

Вывод, обозначенный как GP06 на нижней стороне платы, имеет маркировку D4 на верхней стороне платы. Это контакт 4.

из https://learn.adafruit.com/adafruit-feather-rp2040-pico/pinouts

D4/GP06 — контакт 4 цифрового ввода-вывода. Это также SPI0 SCK, I2C1 SDA и PWM3 A.

,