Piattaforma PlatformIO - framework: Arduino - board: rpipicow - core: earlephilhower
S.O.: windows 10 - Scheda: Raspberry Pi Pico W
Ho una scheda Pico W collegata al PC tramite cavo alla porta USB che crea una porta seriale tramite USB (su PC viene ad esempio identificata come COM4); la stessa scheda è collegata allo stesso PC anche tramite bluetooth con libreria SerialBT (rfcomm) (su PC viene ad esempio identificata come COM5 e COM6).
Ho attualmente un programma che funzionava solo col collegamento seriale via USB che richiama sempre la funzione "Serial." per comunicare col PC (il programma è lungo e richiama la funzione "Serial." molte volte e non vorrei fare molti cambiamenti).
Da programma su Pico W vorrei scegliere se usare la seriale USB o la seriale Bluetooth per trasmettere i dati al PC, lasciando comunque tutte le chiamate inalterate a 'Serial.".
Potrei farlo in sede di compilazione con una #define Serial SeriaBT, ('Serial' usa seriale USB - 'SerialBT' usa seriale Bluetooth), ma vorrei invece decidere in sede di esecuzione del codice a seconda di alcune scelte.
Esiste un metodo per assegnare 'dinamicamente' (non so se mi sono spiegato bene), la funzione 'Serial' ad un'altra funzione che comunque ha gli stessi metodi ?
In pratica ad un certo punto del codice, in base ad alcune condizioni, dire che la funzione Serial, pur lasciandola scritta così com'è, mi richiami la funzione SerialBT .
Potresti farmi un esempio di codice veloce che non sono tanto esperto e poi faccio delle prove ?
Ipotizziamo che cambio tutte le parole 'Serial' con 'SerialOF' (quindi nel codice ad esempio al posto di Serial.read ci sarà SerialOF.read, al posto di Serial.avaliabe() ci sarà SerialOF.avaliable(), al posto di Seria.printf("Prova") ci sarà SerialOF.printf("Prova"), ecc.ecc.).
Io devo, a seconda di una condizione, quando richiamo SerialOF, far eseguire o 'Serial' o 'SerialBT' (i metodi sono gli stessi, ma cambia l'implementazione, il primo fa seriale su USB e l'altro la fa tramite Bluetooth)
Per il momento grazie.
Bè, se ti riferisci alle indicazioni che allora hai dato a me, sì che lo avevo provato. E funzionava (funziona) piuttosto bene.
In sostanza, lato arduino Mega (sul quale agisce il TFT per i comandi, anche di commutazione seriale):
Stream* MYSERIAL;
...
Serial1.begin(BAUD1); // via cavo
Serial2.begin(BAUD2); // via Bluetooth (MASTER)
MYSERIAL = &Serial1; // Default via cavo
Successivamente, sintetizzando, tramite TFT, dò la stringa di commutazione seriale per attivare il bluetooth lato Arduino Due (e Mega, contemporaneamente).
MYSERIAL->print(":BTON#"); // Bluetooth On
Il alto Arduino Due recepisce la stringa (ometto la parte di recepimento e lettura stringa) e dà il comando:
MYSERIAL = &Serial2; // Arduino Due commuta in bluetooth
Sto andando a memoria perché si tratta di un vecchio progetto, che però funziona molto bene. Come richiede l'autore del post, è un comando dinamico, che funziona per commutare la seriale da bluetooth a cavo, e viceversa, tra due unità Arduino.
Ciao
Grazie ... gentilissimi .. dopo lo provo
.. altra DOMANDA:
.. c'è un modo per scrivere "MYSERIAL.print(":BTON#");" anzichè "MYSERIAL->print(":BTON#");"
..ovvero il '.' anzichè '->' ?
comunque noi avevamo anche scritto un programmino di prova:
/*
Una nuova idea DDD
Del Dinamico Duo
Sentitevi liberi di copiare
Sentitevi liberi di trarre ispirazione
Sentitevi liberi di dare un cenno di ringraziamento
// su ispirazione di una vecchia discussione, che non troviamo più
// trovata: era di Standardoil,
Creato con IDE 1.8.10
*/
#include <SoftwareSerial.h>
// solo per avere una seconda seriale
SoftwareSerial mySerial(10, 11); // RX, TX
Stream * flusso;
void setup()
{
mySerial.begin(9600);
Serial.begin(9600);
}
void loop()
{
flusso = & Serial;
// commuto su una seriale
delay(100);
flusso->print("01 ");
// occhio all'uso dell'operatore freccia, invece dell'operatore punto
// obbligatorio se si tratta di puntatori ad oggetti invece degli oggetti puntati
flusso = & mySerial;
//commuto sull'altra
delay(100);
flusso->print("02 ");
}
Mi rispondo da solo, vi chiedo solo la cortesia di confermarmi che ciò che dico è corretto:
supponendo:
Stream* MYSERIAL;
MYSERIAL = & Serial;
.. scrivere (*MYSERIAL).print("prova") è equivalente a scrivere MYSERIAL->print("prova");
Giusto ?
..a questo punto potrei semplicemente sostituire tutti i Serial.read(), Serial.begin(), Serial.peek(), ecc.ecc. in (*MYSERIAL).read(), (*MYSERIAL).begin(), (*MYSERIAL).peek(), ecc.ecc.
..e potrei farlo con una #define Serial (*MYSERIAL)
Il sistema che ho scritto sopra funziona, l'ho provato. .... ma
La Classe Stream (comune sia a Serial che a SerialST che la derivano), non ha però la definizione dell'operatore bool, che invece hanno le classi Serial e SerialBT che serve per sapere se la connessione è attiva (if (Serial) print("Connessione via cavo attiva") .. if (SerialBT) printf("Connessione bluetooth attiva");.
Pertanto il sistema studiato funziona per tutte le chiamate, ad eccezione dell'operatore 'bool' per capire se la connessione è attiva, questo perchè la classe virtuale Stream non prevede la definizione di tale operatore, che viene invece implementata nelle classi Serial e SerialBT.
Pertanto vi chiedo se avete qualche idea ?
... guardando i sorgenti vedo che l'operatore booleano, che ti da lo stato della porta seriale, è effettivamente definito nella classe Serial e non nella classe Stream, oltretutto, nella Serial ritorna sempre e solo "true" mentre nella SerialUSB (che poi è la seriale usata dalle schede con USB nativa), fa effettivamente le dovute verifiche e ritorna di conseguenza.
Ho anche un altra domanda, se riuscite ad aiutarmi.
Quando associo tramite bluetooth la prima volta il pico w a windows (servizio HID + serialBT (rfcomm)), windows me lo riconosce, configura regolamente i dispositivi, lo associa e lo connette. Se spengo tutto, quando riaccendo mi trovo ancora il dispositivo associato, ma non si connette in automatico. Qualcuno sa come posso fare per farlo connettere in automatico ? Immagino che debba impostare qualcosa con le funzione di configurazione del 'gat', non so, sto andando un po' a tentativi.
Le attuali impostazioni del 'gat' che ho sono le seguenti.
gap_discoverable_control(1);
gap_set_class_of_device(hidClass);
gap_set_local_name(localName);
gap_set_default_link_policy_settings(LM_LINK_POLICY_ENABLE_ROLE_SWITCH | LM_LINK_POLICY_ENABLE_SNIFF_MODE);
gap_set_allow_role_switch(true);
Non so se creare un nuovo post ... ma prima provo qui
Quando tramite il Pico W e la libreria SerialBT creo una porta seriale Bluetooth sul PICO W che poi associo a Win10, mi vengono create su windows due porte COM, una delle quale inutilizzabile in quanto risulta perennemente occupata. Utilizzando l'altra (che presumo sia una sorta di collegamento virtuale all'altra), non riesco ad inviare dati e pure inviando dati dal pico W verso windows non ricevo nulla. Qualcuno ha già avuto stesso problema ed ha risolto. E' da un po' che cerco soluzioni, ma non ho trovato ancora nulla.