problema seriale

Codice plz XD.
Se usi la analogWrite() puoi usare la read() di arduino per prendere il byte in arrivo(valore tra 0 e 255 proprio come serve a te).
Potresti usare anche la parseInt() ma occhio ai separatori tra i numeri.

Senza sketch e descrizione dei colelgamenti dei LED e odello Arduino che usi posso solo risponderti:
Sí puó essere.

Ciao Uwe

Allora, ho usato un atmega328 con il bootloader dell'arduino uno e ho inserito questo sketch:

int led = 6;
int tonalita = 0;

void setup() {
        Serial.begin(9600);
}

void loop() {

        if (Serial.available() > 0) {
          
                tonalita = Serial.read();

                analogWrite(led, tonalita);
        }
}

Il programma visual basic invece è come ho descritto, c'è una trackbar che restituisce un valore (da 0 a 255) che viene scritto sulla seriale, ogni decimo di secondo. La porta com è giusta.

Il problema è che una volta che muovo la barra il led (che appena inserito lo sketch è spento) si accende ma poi non cambia più luminosità in base al movimento ma resta fisso. Idee?

Perché non spedisci il valore della tonalità ricevuta al Serial Monitor?

Prova ad usare anche il serial monitor come interfaccia per verificare se è lo sketch (che mi sembra giusto) o il programma in VB.

cyberhs:
Perché non spedisci il valore della tonalità ricevuta al Serial Monitor?

Perché la seriale può essere usata da un solo dispositivo alla volta e se il programmino è aperto (e quindi connesso con la COM) non mi fa aprire il monitor.

Mostra anche il codice Visual Basic, forse è lì che c'è qualcosa da sistemare.

  1. anche se non dovrebbe essere necessario, comunque per pulizia sarebbe meglio settare il pinMode nella setup()
    pinMode(led, OUTPUT);

  2. come spedisci il dato da VB? un singolo byte da 0-255 o il valore come stringa (esempio 123 come "123" e perciò 3 byte=49-50-51) ?
    Secondo me:
    in VB6 usando il controllo MsComm spedisci con il comando MSCom3.Output = text ma anche la output si aspetta una stringa, perciò
    un valore da variabile numerica lo converte in stringa. MSCom3.Output = MyScroll.Value 123->"123"
    In VB6 dovresti provare MSCom3.Output = Chr$(MyScroll.Value) 123->carattere in tabella ascii 123 perciò un byte

Il codice visual basic è questo:

    Private Sub TrackBar1_Scroll(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TrackBar1.Scroll
        TrackBar1.Minimum = 0
        TrackBar1.Maximum = 255
        Timer1.Start()

    End Sub

    Private Sub Label1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Label1.Click

    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        myport = IO.Ports.SerialPort.GetPortNames
        ComboBox1.Items.AddRange(myport)  'inserisco porte seriali disponibili in combobox1
    End Sub

    Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged

        SerialPort1.Close()
        SerialPort1.PortName = ComboBox1.Text
        SerialPort1.Open()
        ComboBox1.Enabled = False
    End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        Dim i As Byte
        i = CByte(Val(TrackBar1.Value))  'converto la stringa in byte
        Label1.Text = i  'mostro il valore nella label1
        SerialPort1.Write(i)  'invio il valore alla seriale

    End Sub
End Class

All'inizio il programma non prevedeva la conversione da stringa a byte, ma vedendo che non funzionava ho aggiunto la conversione (anche se la Label1 mi mostra sempre il numero). Usando lettere dell'alfabeto (per altri programmi) funzionava benissimo (senza conversione) ma con i numeri non ci sono mai riuscito!

Secondo me quella conversione è inutile.
Prendi un numero TrackBar1.Value, esempio 123
Lo converti in numero Val() quindi hai 123
E poi obblighi VB a convertire 123->"123" e poi ancora in 123 con CByte()

La SerialPort.Write si aspetta una stringa, perciò il byte viene convertito in stringa (sequenza di cifre) e sparerà "1" "2" e poi "3" se la cifra è 123

Se vuoi una sola cifra devi sostituire
i = CByte(Val(TrackBar1.Value))
con
i = Chr(TrackBar1.Value) 'converto la stringa in byte 123=>"{"

Ho provato ad aprire il monitor seriale (quindi senza applicazione VB) e a scrivere dei numeri da 0 a 255 e la situazione non cambia lo stesso...quindi il problema è nel sketch arduinico! ora la domanda è dov'è l'errore!

Stesso errore. Se tu scrivi sul monitor 123, stai scrivendo "1" "2" e "3"
Ovvero Arduino riceverà tre byte "1", "2" e "3" ovvero i valori 49, 50 e 51

Se vuoi fare la prova devi scrivere un solo carattere il cui valore ascii è il valore che vuoi spedire. Ad esempio { => 123
Purtroppo da tastiera non puoi provare tutti i valori.
Prova # => 35
Poi prova { => 123
poi con ± => 241 (questo non sò se il serial monitor dell'IDE lo prende)

Ah ho capito! Infatti adesso ho usato la funzione chr come dicevi prima tu (prima l'avevo inserita male) ma sorge un'altro problema: arrivato ad un certo valore (corrisponde al simbolo €) il led non cambia più di valore, forse arduino non legge tutti i caratteri ascii che ha vb?

No, penso sia ora un problema elettronico.
Forse con quel valore hai già la massima luminosità del led.

P.S. quanto vale € ?

nid69ita:
No, penso sia ora un problema elettronico.
Forse con quel valore hai già la massima luminosità del led.

P.S. quanto vale € ?

Corrisponde a 128. Ho pensato che l'ascii arriva a 127 (cioè 7bit) e infatti fino a quel numero va tutto ok. Ho ovviato al problema impostanto il massimo della trackbar a 127 e usando nell'arduino la funzione map per riportarlo all'intervallo 0-255

Ma nel tuo sketch tonalita è ancora int?
prova a cambiarlo in
unsigned char tonalita = 0; // da 0-255
oppure
unsigned int tonalita = 0;

Non credo funzioni visto che Serial.read() torna un int.

Nel programma Visual Basic usa il metodo Write con il buffer di byte :SerialPort.Write Metodo (System.IO.Ports) | Microsoft Learn così eviti la conversione in stringa e puoi usare numeri fino a 255.

yoshi93:
Non credo funzioni visto che Serial.read() torna un int.

in automatico il C farà un cast. Non perdi numeri perchè ricevi solo byte.
Puoi anche forzarlo: tonalita = (unsigned char)Serial.read();

An già, il cast automatico, io di solito lo faccio sempre esplicito e mi ero anche dimenticato dell'aiuto del compilatore :grin:.