Rasberry PI PICO (RP2040) продолжение темы

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

1 лайк

Блин ну не получается и все считать данные

Вот скетч

#include <Arduino.h>
#include <ModbusMaster.h>

// Настройка UART для RS-485
UART Serial2(0, 1, 0, 0);  // TX на GP8, RX на GP9
#define rs485_control_pin 12

// Создаем объект ModbusMaster
ModbusMaster node;

// Адреса регистров
const uint16_t concentration_address = 0x00; // Адрес концентрации
const uint16_t threshold1_address = 0x02;    // Адрес порога 1
const uint16_t threshold2_address = 0x04;    // Адрес порога 2

void preTransmission() {
    digitalWrite(rs485_control_pin, HIGH);  // Включение передачи
}

void postTransmission() {
    digitalWrite(rs485_control_pin, LOW);   // Включение приема
}

void setup() {
    Serial.begin(9600);          // Начинаем работу с Serial для отладки
    Serial2.begin(9600);        // Начинаем работу с Serial2 для RS-485
    pinMode(rs485_control_pin, OUTPUT);
    digitalWrite(rs485_control_pin, LOW); // Изначально устанавливаем в режим приема

    node.begin(1, Serial2);     // Устанавливаем адрес устройства (1)
    node.preTransmission(preTransmission);
    node.postTransmission(postTransmission);
}

void loop() {
    uint8_t result;
    uint16_t data[2];

    // Чтение концентрации
    result = node.readHoldingRegisters(concentration_address, 2);
    if (result == node.ku8MBSuccess) {
        data[0] = node.getResponseBuffer(0);
        data[1] = node.getResponseBuffer(1);
        Serial.println("Измеренное значение концентрации:");
        displayConcentration(data);
    } else {
        Serial.print("Ошибка чтения концентрации. Код ошибки: ");
        Serial.println(result, HEX);
    }

    // Чтение порога 1
    result = node.readHoldingRegisters(threshold1_address, 1);
    if (result == node.ku8MBSuccess) {
        uint16_t threshold1 = node.getResponseBuffer(0);
        displayThreshold(threshold1, "Порог 1");
    } else {
        Serial.print("Ошибка чтения первого порога. Код ошибки: ");
        Serial.println(result, HEX);
    }

    // Чтение порога 2
    result = node.readHoldingRegisters(threshold2_address, 1);
    if (result == node.ku8MBSuccess) {
        uint16_t threshold2 = node.getResponseBuffer(0);
        displayThreshold(threshold2, "Порог 2");
    } else {
        Serial.print("Ошибка чтения второго порога. Код ошибки: ");
        Serial.println(result, HEX);
    }

    delay(3000);  
}

// Функции для отображения концентрации и порогов
void displayConcentration(uint16_t registers[]) {
    if (registers == nullptr) {
        Serial.println("Недостаточно данных для отображения концентрации");
        return;
    }

    uint8_t byte1 = (registers[0] >> 8) & 0xFF;
    uint8_t byte2 = registers[0] & 0xFF;
    uint8_t byte3 = (registers[1] >> 8) & 0xFF;
    uint8_t byte4 = registers[1] & 0xFF;

    bool sign_bit = (byte1 >> 7) & 0x01;
    uint8_t comma_position = byte1 & 0x07;

    int32_t integer_part = (int32_t)byte2 * 10000L + (int32_t)byte3 * 10L + (byte4 >> 4);
    int32_t decimal_part = (byte4 & 0x0F) * 100;

    double value = integer_part + decimal_part / 10000.0;
    value = sign_bit ? -value : value;

    double divisor = 1.0;
    for (uint8_t i = 0; i < comma_position; i++) {
        divisor *= 10.0;
    }
    value /= divisor;

    value = round(value * 100.0) / 100.0;

    Serial.print("Концентрация: ");
    Serial.println(value, 2);
}

void displayThreshold(uint16_t threshold, const char* thresholdName) {
    Serial.print(thresholdName);
    Serial.print(" - ");
    Serial.println(threshold & 0xFF, HEX);  // Выводим только младший байт
}

Ошибка чтения концентрации. Код ошибки: E2

Ошибка чтения первого порога. Код ошибки: E2

Ошибка чтения второго порога. Код ошибки: E2

Решил все переписать с нуля) так что процесс пошел потихоньку , всем спасибо)

Отлаживание устройств на базе RP2040 в ARDUINO IDE, отладчик на такой же плате, программа отладчика доступна по ссылке.

эта строчка пытается запустить Serial2 на пинах 0 и 1, где уже есть Serial

А вообще ваша главная проблема в том, что вы никак не поймете - для Расберии Пико в среде Ардуино существует несколько аддонов. Эти аддоны не совместимы между собой. Код для одного аддона не будет работать на другом.

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

Возникла интересная ситуация с RP2040. Черная, китайская, 16 мег. Загружаю программу, после прошивки она запускается, это просто проверка работы с TFT экраном. При этом RP2040 по прежнему соединена по USB c компьютером. Если модуль с экраном попробовать запитать просто через USB разьем, ( пробовал и другой вариант) то программа не запускается. Проверено на двух платах, эффект воспроизводится 100% Складывается впечатление, что запуск программы происходит после коннекта с IDE. Что это может быть и как это преодолеть ?

Код покажите

Ответ на мой вопрос нашел. И он не в коде. При использовании для отладки Serial при запуске программы, вероятно, происходит взаимодействие с IDE (инициализация интерфейса с монитором COM порта через USB), и программа нормально запускается. При автономном питании такого взаимодействия нет, и программа не запускается. Если Serial не используется, то при автономном питании все хорошо.
Решение -

  1. Не использовать Serial .
  2. Просто перейти на Serial1, но тогда придется обеспечить через дополнительный (CH340 например) переходник получение отладочных сообщений с соответствующих пинов в отдельную программу-монитор COM порта ).
    И, кстати об автономном питании - внешний источник питания надо подключать через диод ( желательно Шоттки ) в точку VOut (VSYS). Увидел по схеме питания RP2040, и убедился в правильности решения по документации. В ней есть несколько вариантов питания. Этот вариант позволяет развязать питание от USB при отладке от автономного питания , которое тоже должно быть включено для питания периферийных модулей. Периферийные модули могут иметь и отдельное питание, при наличии общей земли и соблюдении уровней сигнала в 3,3 вольта при подключении к пинам RP2040.
    К примеру, экран TFT 3,5 " своим питанием ( плюс его подсветка ) через встроенный в RP2040 преобразователь ( пин 3V3 ) просадил выходное напряжение для процессора до 3,1 вольта, что нежелательно. Пришлось его обеспечить отдельным питанием.
    И, кстати, мои черные модули RP2040 16M определились как Waveshare RP2040 Pico, эта плата есть у Филховера, при этом видны все 16M и варианты ее распределения.

Уточню - платы определились как
Waveshare RP2040 PLUS 4MB
VID = 0x2E8A
PID = 0x1020
при этом видны 16M

посмотрите, нет ли у вас в коде (обычно в сетап) строчки

if ( ! Serial) {

если есть - то программа нуждается в подключении к Ардуино Монитору при запуске и без него работать не будет.

Я же вас просил выложить код, а вы темните

Да, все именно так. Вы правы.

уберите эту строку и все заработает…

Уже заработало. В своих проектах я иногда выделяю отдельный пин и джампер на плате и по нему определяю - открывать ли Serial и выводить отладочные сообщения или нет. В этот раз до этого не дошло…


Во! УНО форма появилась. Продавцов много, покупок мало.

косарь с лишним О_о

3 лайка

Ну интересно же. Там переключатель какой то под rx tx , наверное чтоб плату быстрей сжечь.

Так для информации
Дефолтная частота ядра RP2040 в аддоне Филхофера теперь 200 МГц.
Это касается в том числе и старых плат, так что если кто привязывался к конкретной частоте 133 МГц - имейте в виду.

Блин, я удивляюсь, что кто-то еще покупает AVR

На этой RP памойму при желании можно MSDOS запустить 7.0

1 лайк

она врят ли поддерживает два ядра)

операционная система MS-DOS.