Interfaccia display con scheda Arduino

Specifiche display


Software

// commands
#define LCD_CLEARDISPLAY 0x01
#define LCD_RETURNHOME 0x02
#define LCD_ENTRYMODESET 0x04
#define LCD_DISPLAYCONTROL 0x08
#define LCD_CURSORSHIFT 0x10
#define LCD_FUNCTIONSET 0x20
#define LCD_SETCGRAMADDR 0x40
#define LCD_SETDDRAMADDR 0x80
// flags for display entry mode
#define LCD_ENTRYRIGHT 0x00
#define LCD_ENTRYLEFT 0x02
#define LCD_ENTRYSHIFTINCREMENT 0x01
#define LCD_ENTRYSHIFTDECREMENT 0x00
// flags for display on/off control
#define LCD_DISPLAYON 0x04
#define LCD_DISPLAYOFF 0x00
#define LCD_CURSORON 0x02
#define LCD_CURSOROFF 0x00
#define LCD_BLINKON 0x01
#define LCD_BLINKOFF 0x00
// flags for display/cursor shift
#define LCD_DISPLAYMOVE 0x08
#define LCD_CURSORMOVE 0x00
#define LCD_MOVERIGHT 0x04
#define LCD_MOVELEFT 0x00
// flags for function set
#define LCD_8BITMODE 0x10
#define LCD_4BITMODE 0x00
#define LCD_2LINE 0x08
#define LCD_1LINE 0x00
#define LCD_5x10DOTS 0x04
#define LCD_5x8DOTS 0x00
#define  _rs_pin       12  //RS 
#define  _enable_pin   11  //EN

uint8_t  _data_pins[4]={
                       5, //D4
                       4, //D5
                       3, //D6
                       2  //D7
                     };  

uint8_t _displayfunction;
uint8_t _displaycontrol;
uint8_t _displaymode;
uint8_t _numlines = 2;
uint8_t _currline = 0;

void pulseEnable(void) {
  digitalWrite(_enable_pin, LOW);
  delayMicroseconds(1);    
  digitalWrite(_enable_pin, HIGH);
  delayMicroseconds(1);    // enable pulse must be >450ns
  digitalWrite(_enable_pin, LOW);
  delayMicroseconds(200);   // commands need > 37us to settle
}

void write4bits(uint8_t value) {
  for (int i = 0; i < 4; i++) {
    pinMode(_data_pins[i], OUTPUT);
    digitalWrite(_data_pins[i], (value >> i) & 0x01);
  }
  pulseEnable();
}

void WrDBus(uint8_t value)
{
  write4bits(value>>4);
  write4bits(value);  
}  

void command(uint8_t value) {  
  digitalWrite(_rs_pin, LOW);
  WrDBus(value);
}

void wrdata(uint8_t value) {
  digitalWrite(_rs_pin, HIGH);
  WrDBus(value);
}

// Turn the display on/off (quickly)
void noDisplay() {
  _displaycontrol &= ~LCD_DISPLAYON;
  command(LCD_DISPLAYCONTROL | _displaycontrol);
}
void display() {
  _displaycontrol |= LCD_DISPLAYON;
  command(LCD_DISPLAYCONTROL | _displaycontrol);
}

/********** high level commands, for the user! */
void clear()
{
  command(LCD_CLEARDISPLAY);  // clear display, set cursor position to zero
  delay(10);  // this command takes a long time!
}

void setCursor(uint8_t col, uint8_t row)
{
  int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };
  if ( row >= _numlines ) {
    row = _numlines-1;    // we count rows starting w/0
  }  
  command(LCD_SETDDRAMADDR | (col + row_offsets[row]));
}

void WrStr(String a)
{
  for (int i = 0; i < a.length(); i++) {
   wrdata(a[i]);    
  }
}  

void initLCD()
{  
  pinMode(_rs_pin, OUTPUT);
  pinMode(_enable_pin, OUTPUT);  
  _displayfunction = LCD_4BITMODE | LCD_2LINE | LCD_5x8DOTS;
  _numlines = 2;
  _currline = 0;
  // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION!
  // according to datasheet, we need at least 40ms after power rises above 2.7V
  // before sending commands. Arduino can turn on way befer 4.5V so we'll wait 50
  delayMicroseconds(50000); 
  // Now we pull both RS and R/W low to begin commands
  digitalWrite(_rs_pin, LOW);
  digitalWrite(_enable_pin, LOW);  
  // this is according to the hitachi HD44780 datasheet
  // figure 24, pg 46
  // we start in 8bit mode, try to set 4 bit mode
  write4bits(0x03);
  delayMicroseconds(4500); // wait min 4.1ms
  // second try
  write4bits(0x03);
  delayMicroseconds(4500); // wait min 4.1ms    
  // third go!
  write4bits(0x03); 
  delayMicroseconds(150);
  // finally, set to 4-bit interface
  write4bits(0x02); 
  // finally, set # lines, font size, etc.
  command(LCD_FUNCTIONSET | _displayfunction);  
  // turn the display on with no cursor or blinking default
  _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;  
  display();
  // clear it off
  clear();
  // Initialize to default text direction (for romance languages)
  //_displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
  // set the entry mode
  //command(LCD_ENTRYMODESET | _displaymode);
}

/*
01234567890123456789 
A0:0.000   A1:0.000
A2:0.000   A3:0.000
*/        

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  initLCD(); 
  WrStr("A0:");
  setCursor(11, 0);
  WrStr("A1:");
  setCursor(0, 1);
  WrStr("A2:");
  setCursor(11, 1);
  WrStr("A3:");  
}

void loop() {
  char b[30];    
  setCursor(3, 0);  
  dtostrf(analogRead(0)*5.0/1023,5, 3,b);  
  WrStr(b);
  Serial.print("A0:");Serial.print(b);
  setCursor(14, 0);  
  dtostrf(analogRead(1)*5.0/1023,5, 3,b);    
  WrStr(b);
  Serial.print(" A1:");Serial.print(b);
  setCursor(3, 1);  
  dtostrf(analogRead(2)*5.0/1023,5, 3,b);    
  WrStr(b);
  Serial.print(" A2:");Serial.print(b);
  setCursor(14, 1);  
  dtostrf(analogRead(3)*5.0/1023,5, 3,b);  
  WrStr(b);
  Serial.print(" A3:");Serial.println(b);
}

Alimentatore switching stabilizzato con regolazione di corrente e tensione gestito da sistema a microcontrollore

(Hardware aggiuntivo all' interfaccia display con scheda Arduino)

Software

/*
  Alimentatore con regolazione di tensione e corrente di CC.
  gestito da microcontrollore
*/
#define VoutPin  A0  //Ingresso analogico per misura tensione di uscita     
#define IoutPin  A1  //Ingresso analogico per misura corrente di uscita     
#define TempPin  A2  //Ingresso analogico per misura temperatura transistor di potenza       
#define UpPin     6  //Ingresso pulsante UP per impostazione riferimento
#define DwPin     7  //Ingresso pulsante DW per impostazione riferimento
#define OkPin     8  //Ingresso pulsante OK per scelta VRe IRef
#define PWMPin   10  //Uscita PWM 

#define Vfs 12.0     //Fondoscala in misura tensione di uscita (V)
#define Ifs 2.0      //Fondoscala in misura corrente di uscita (I)
//Variabili
int Vout,            //Ultimo valore di tensione di uscita letto in val ADC (0..1023)
    Iout,            //Ultimo valore di corrente di uscita letto in val ADC (0..1023)  
    RVout=0,         //Valore di tensione di riferimento in val ADC (0..1023)
    RIout=0,         //Valore di corrente di riferimento in val ADC (0..1023)  
    PWmOut=0;        //Valore del PWM di uscita 
unsigned long time;  //variabile per elaborazione ritardi
int sel=0;           //puntatore alla valore da modificare (RVout o RIout)
char b[30];          //buffer di appoggio per le stampe su display
int rit=50;          //ritardo repeat tasti (ms)

//Stampa su display i valore di RVout in Volt
void PrRefV()
{
  setCursor(3, 1);   
  dtostrf(RVout*Vfs/1023,5, 2,b);  
  WrStr(b);    
}  
//Stampa su display i valore di RIout in Volt
void PrRefI()
{
  setCursor(12, 1);  
  dtostrf(RIout*Ifs/1023,4, 2,b);    
  WrStr(b);  
}  
//-----------------------------------------------------------------
void setup() {
  //Inizializzazione ingressi tastrierino in modalità pull-up
  pinMode (UpPin,INPUT_PULLUP);
  pinMode (DwPin,INPUT_PULLUP);
  pinMode (OkPin,INPUT_PULLUP);
  initLCD();
  //Scrive i testi statici sul display 
  WrStr("Vo:");
  setCursor(9, 0);
  WrStr("Io:");
  setCursor(0, 1);
  WrStr("RV:");
  setCursor(9, 1);
  WrStr("RI:");  
  //Scrive il valore iniziale  RVout e RIout 
  PrRefV();
  PrRefI();
}
//-----------------------------------------------------------------
void Regolatore()
{ 
  //Limitazione di corrente
  if (Iout>RIout)
  {
    PWmOut--;
  }
  else  
  {
    //Regolazione di tensione
    if (Vout>RVout)
      PWmOut--;
    if (Vout<RVout)
      PWmOut++;      
  }  
  //Tosatore
  if (PWmOut>255) PWmOut=255;
  if (PWmOut<0)   PWmOut=0;
  //Output del valore PWM
  analogWrite(PWMPin,PWmOut);
}  

//-----------------------------------------------------------------
void loop() {
  //Legge Vout e Iout
  Vout=analogRead(VoutPin);
  Iout=analogRead(IoutPin);
  //Scrive su display i valori di Vout e Iout appena letti
  setCursor(3, 0);  
  dtostrf(Vout*Vfs/1023,5, 2,b);  
  WrStr(b);
  setCursor(12, 0);  
  dtostrf(Iout*Ifs/1023,4, 2,b);    
  WrStr(b);
  
  //Esegue la funzione di regolazione
  Regolatore();
  
  //Blocco gestione tastierino  
  if (millis()>(time+rit))
  {   
    //Verifica se OK è premuto 
    if (!digitalRead(OkPin))
    {
      //Imposta ritardo di autorepeat in caso di pressione continua
      time=millis();
      rit=500;
      //incrementa selettore grandezza da modificare
      sel++;
      if (sel > 1)
        sel=0;
      //Evidenzia su display con il carattere ">" la grandezza abilitata alla modifica  
      switch (sel)
      {
        case 0:
          setCursor(2, 1);   
          WrStr(">");  
          setCursor(11, 1);  
          WrStr(":");  
        break;
        case 1:
          setCursor(2, 1);   
          WrStr(":");  
          setCursor(11, 1);  
          WrStr(">");            
        break;
      }          
    }  
    //Verifica se Up è premuto 
    if (!digitalRead(UpPin))
    {
      //Imposta ritardo di autorepeat in caso di pressione continua
      time=millis();
      rit=50;
      switch (sel)
      {
         //incrementa RVout
         case 0:
           if (RVout<1023)
           {
             RVout++;
             PrRefV();
           }  
         break;   
         //incrementa RIout
         case 1:
           if (RIout<1023)
           {
              RIout++;
              PrRefI();
           } 
         break;            
      }            
    }  
    //Verifica se Dw è premuto 
    if (!digitalRead(DwPin))
    {
      //Imposta ritardo di autorepeat in caso di pressione continua
      time=millis();
      rit=50;
      switch (sel)
      {
         //decrementa RVout
         case 0:
           if (RVout>0)
           {
              RVout--;
              PrRefV();
           }   
         break;   
         //decrementa RIout
         case 1:
           if (RIout>0) 
           {
             RIout--;
             PrRefI();
           }
         break;            
      }            
    }      
  }
}