PlatformIO Community

Serial Communication micro USB on Pi Pico C++

Bonjour,

Explication rapide de mon problème.

J’ai développé un programme win form en C# utilisant IO.Ports pour communiquer avec un arduino (c++) : cela fonctionne

J’ai développé ce même programme utilisant IO.Ports pour communiquer avec un raspberry Pi Pico (c++) : cela ne fonctionne pas

J’ai donc essayé de communiquer avec ce Pico via Putty : cela fonctionne

La communication envoi réception Putty / Pico fonctionne mais la communication envoi réception C# / Pico ne fonctionne pas

Merci d’avance

— DeepL translation —

Hello,

Quick explanation of my problem.

I developed a win form program in C# using IO.Ports to communicate with an arduino (c++) : it works

I developed this same program using IO.Ports to communicate with a raspberry Pi Pico (c++) : it does not work

I tried to communicate with this Pico via Putty : it works

The Putty / Pico send-receive communication works but the C# / Pico send-receive communication does not work

Thanks in advance

Do you have a minimal C# program and C++ firmware (+ platformio.ini) for reproduction?

Oui,

voici mon c++ sur le Pico

#include <HardwareSerial.h>

#define LED LED_BUILTIN
#define SORTIE 18

byte buffer_recoi[2];

String texte = "c'est pas bon";

void setup() {
  pinMode(SORTIE, OUTPUT);
  pinMode(LED, OUTPUT);
  _UART_USB_.begin(115200, SERIAL_8N1);
}

void loop() 
{
  if(SerialUSB.available())
  { 
    SerialUSB.readBytes(buffer_recoi, 2);
    if (buffer_recoi[0] == 97)
    {
      if (buffer_recoi[1] == 97)
      {
        digitalWrite(LED, HIGH);
        digitalWrite(SORTIE, HIGH);
      }
      else if (buffer_recoi[1] == 122)
      {
        digitalWrite(LED, LOW);
        digitalWrite(SORTIE, LOW);
      }
    }
    SerialUSB.print(".");
    SerialUSB.flush();
  }
}

et voici le c# pour mon winform,


        public SerialPort Pico = new SerialPort("COM5", 115200, Parity.None, 8, StopBits.One);  

Mon programme bloque sur cette ligne : Pico.Write(pins[id].Allumer(), 0, 2);

Voici la classe dans lequel le programme va chercher le pins[i].allumer

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing;

namespace Testeur_RTE
{
    internal class Pin
    {
        public byte[] trame = new byte[2];     //premier byte = id ;   deuxième byte = fonction
        public Button Bouton;

        public Pin(byte id, Button bouton)         //créer un pin avec un id défini
        {
            this.trame[0] = id;
            this.Bouton = bouton;
        }

        public byte[] Allumer()     //Envoyer 48 V sur la broche
        {
            trame[1] = 0x00;
            return trame;
        }

        public byte[] Eteindre()    //Envoyer 0V sur la broche
        {
            trame[1] = 0x01;
            return trame;
        }

        public void Allumer_bouton()
        {
            Bouton.Location = new Point(Bouton.Left, Bouton.Top + 20);
            Bouton.BackColor = Color.FromArgb(0, 116, 167);
        }

        public void Eteindre_bouton()
        {
            Bouton.Location = new Point(Bouton.Left, Bouton.Top - 20);
            Bouton.BackColor = Color.FromArgb(0x00, 0xA6, 0xD9);
        }

        public byte Recup_ID(object sender)     //Récupère l'id associé au bouton et au pin à partir du tabindex donné en sender
        {
            string sended;
            char[] tab;
            if (sender.ToString().ToCharArray().Length == 36)
            {
                sended = sender.ToString() + "0";
                tab = sended.ToCharArray();
                sended = tab[35].ToString();
            }
            else
            {
                sended = sender.ToString();
                tab = sended.ToCharArray();
                sended = tab[35] + tab[36].ToString();
            }
            return (Convert.ToByte(sended));
        }
    }
}

Je précise que dans le winform général, j’ai en effet fait un Serial.open()

Je reste à votre disposition pour plus de questions, merci de m’aider, cela fait 3 jours que je suis dessus

Just a shot in the dark:

Can you use

and enable DTR (and possible RTS) lines?

Pico.DtrEnable = true;

Putty might set it, but not the C# logic.

1 Like

Merci beaucoup.

Puis-je avoir des explications sur ces la ligne DTR et RTS ?

Merci d’avance

Well when using a hardware UART, DTR (data terminal ready) and RTS (ready to send) are flow control signals between the hardware UART controllers. If one UART wants to send something to another UART controller it can check the state of the e.g. RTS line to check if the other end is ready to receive, otherwise it will wait for the line to become active.

However, in USB serials (aka, USB-CDC), this is a “virtual” signal, just a boolean value. Still, the USB stacks and USB-CDC logic may use the value of DTR and RTS (which is then set via USB packets of type SET_CONTROL_LINE_STATE) to detect whether they are connected to a computer or not. You can e.g. see this in

For the Arduino-mbed core (which you are probably using with your Pico).

If DTR is is not set, then the core will always return false for ready().

The same happens in other USB CDC libraries, like TinyUSB used by the (EarlePhilhower) Arduino-Pico core

So without the DTR line active, many USB-CDC implementations will not see the connection as “established” and won’t accept or send data. But this can still differ from implementation and implementation. Many USB-Serial converter chips (such as those on Arduino Uno / Nano etc. boards) like the CH340 or CP2102 don’t seem to need that.

See

1 Like