Ho preso un Kingbringht Dot Led Matrix Display (datasheet Kingbright Electronic 157524, 1 datasheet pdf): una matrice di LED 7x5.
Per l'occasione ho scritto sull'arduino questo semplice firmware: un parser dei comandi che gli invio sulla serial.
// array that will hold the bytes of the incoming string.
#define inBUF 14
char inBuffer[inBUF];
// read a string from the serial and store it in an array
// you must supply the array variable
void readSerialString (char *strArray)
{
int i=0;
while (true)
{
if (Serial.available())
{
while (Serial.available())
{
strArray[i] = Serial.read();
i++;
}
if (strArray[i-1] == '
Quindi sul lato PC ho realizzato un semplice programmino in C# con mono.
using System;
using System.IO;
using System.IO.Ports;
using System.Threading;
namespace BlikALed
{
class MainClass
{
public static void Main(string[] args)
{
// Init Porta seriale RS-232
SerialPort rs232 = new SerialPort("/dev/ttyUSB0", 115200, Parity.None, 8, StopBits.One);
// Apertura della porta
try
{
rs232.Open();
// È necessario aspettare un tempo minimo di 1.5 s prima di inviare
// qualsiasi comando alla seriale, pena il non funzionamento di
// ogni comando.
Thread.Sleep(2000);
}
catch (System.IO.IOException ioe)
{
Console.Write(ioe.Message);
Environment.Exit(1);
}
// Setup pins
rs232.Write("SOOOOOOOOOOOO$");
//rs232.Write("DLLLLLLLLLLLL$");
Thread.Sleep(200);
// mappatura pin 7x5
//int C = {2, 3, 4, 5, 6};
//int R = {7, 8, 9, 10, 11, 12, 13};
// acensione colonne in sequenza
rs232.Write("DLLLLLHHHHHHH$");
Thread.Sleep(150);
for (int i=0; i<100;i++)
{
rs232.Write("DHLHHHHHHHHHH$");
Thread.Sleep(11);
rs232.Write("DHHLHHHHHHHHH$");
Thread.Sleep(11);
rs232.Write("DHHHLHHHHHHHH$");
Thread.Sleep(11);
rs232.Write("DHHHHLHHHHHHH$");
Thread.Sleep(11);
rs232.Write("DHHHHHLHHHHHH$");
Thread.Sleep(11);
rs232.Write("DLHHHHHHHHHHH$");
}
Thread.Sleep(500);
rs232.Write("DLLLLLLLLLLLL$");
// Chiusura porta
rs232.Close();
}
}
}
Il programma a basse velocità funziona bene, non appena riduco i delay le cose non vanno troppo bene. Che salti qualche colonna a volte me lo sarei anche aspettato (ma 115200 bps non è una velocità di trasferimento sufficientemente alta per evitarlo??), quello che non capisco è perchè a volte nella scansione mi accende solo metà colonna o anche solo un led solo, questo proprio non riesco a capirlo. Una volta che sono entrato nella routin di accensione dei led non centra più nulla la seriale e sono dentro all'arduino, quindi non ne trovo un senso.
Come posso migliorare la situazione? Cioè, posso andare a codificare in qualche modo la stringa di comandi che invio sulla seriale riducendo quindi il numero di byte trasmessi oppure mi devo mettere il cuore in pace che anche codificando non guadagnerei abbastanza in velocità? Oppure pensare ad ottimizzare il firmware, invece del pinmode accedere direttamente in assembler alle porte?
Qualche suggerimento?
Ciao
Albano)
{
return;
}
}
}
}
//utility function to know wither an array is empty or not
boolean isStringEmpty (char *strArray)
{
if (strArray[0] == 0)
{
return true;
}
else
{
return false;
}
}
void setup()
{
Serial.begin(115200);
Serial.println("PaceyIV v0.1");
}
void loop ()
{
// read the serial port and create a string out of what you read
readSerialString(inBuffer);
if (isStringEmpty(inBuffer)==false)
{
// echo cmd
Serial.println(inBuffer);
//------------
// "S" = code to setup pins 2-13 as input I or output O
// eg. SIOIOIOIOIOOO
if (inBuffer[0]=='S')
{
for (int i=1; i<=12; i++)
{
if (inBuffer[i]=='I')
{
pinMode(i+1, INPUT);
}
else
{
pinMode(i+1, OUTPUT);
}
}
}
//--------
// "D" = code for digital out to arduino looks for D as first
// character in the input string
// then looks for H & L letters
// for example computer sends DHLHHLLHHHLH
if (inBuffer[0]=='D')
{
for (int i=1; i<=12; i++)
{
if (inBuffer[i]=='H')
{
digitalWrite(i+1, HIGH);
}
else
{
digitalWrite(i+1, LOW);
}
}
}
}
// clean the buffer
for (int i=0; i<=inBUF; i++)
{
inBuffer[i]=0;
}
}
Quindi sul lato PC ho realizzato un semplice programmino in C# con mono.
§DISCOURSE_HOISTED_CODE_1§
Il programma a basse velocità funziona bene, non appena riduco i delay le cose non vanno troppo bene. Che salti qualche colonna a volte me lo sarei anche aspettato (ma 115200 bps non è una velocità di trasferimento sufficientemente alta per evitarlo??), quello che non capisco è perchè a volte nella scansione mi accende solo metà colonna o anche solo un led solo, questo proprio non riesco a capirlo. Una volta che sono entrato nella routin di accensione dei led non centra più nulla la seriale e sono dentro all'arduino, quindi non ne trovo un senso.
Come posso migliorare la situazione? Cioè, posso andare a codificare in qualche modo la stringa di comandi che invio sulla seriale riducendo quindi il numero di byte trasmessi oppure mi devo mettere il cuore in pace che anche codificando non guadagnerei abbastanza in velocità? Oppure pensare ad ottimizzare il firmware, invece del pinmode accedere direttamente in assembler alle porte?
Qualche suggerimento?
Ciao
Albano