Pagina 1 di 1

Rheobus con arduino

Inviato: 13 giu 2011 04:06
da master_of_mouse
Apro questo topic per proporre un progetto a cui tutti possono unirsi e dare supporto ed eventualmente trarre spunto per progetti personali.

Iniziamo col dire cosa voglio ottenere.
Come da titolo il progetto si propone di realizzare un rheobus (o fanbus o baybus o controllo per ventole che dir si voglia) capace di gestire fino a 6 ventole con relativo rilevamento della velocità, lettura di 6 sensori di temperatura e di attivare/disattivare delle "uscite di potenza" per accendere/spegnere le, neon, luci varie e tutto quello che possiamo volerci attaccare.

Uno dei requisiti principali è che deve stare tutto in un 5.25" Drive Bay magari sfruttando il box di qualche vecchio lettore cd/dvd.
Come piattaforma ho scelto un Arduino Mega 2560 dotato di 54 Digital I/O Pins di cui 14 dotati di uscita pwm e 16 Analog Input Pins. Potrebbe sembrare esagerato ma se prendessimo un Arduino Uno ci staremmo a mala pena dentro con le ventole o dovremmo ridurne il numero per pilotare l'lcd e l'encoder.

La Scheda
ArduinoMega2650Front.jpg
ArduinoMega2650Back.jpg
La scheda è larga circa 11cm e profonda circa 5.5cm

L'alimentazione verrà presa dal pc e sdoppiata in due rami, uno che va all'Arduino sul suo connettore d'alimentazione dedicato ed uno che andrà a dare energia a tutto il resto, questo perchè la scheda lavora a 5V ed inoltre le sue uscite non sono in grado di fornire che pochi mA sufficenti ad alimentare l'lcd ed i transistor che vedremo più avanti come utilizzare ma non le ventole e tutto il resto. L'alimentazione deve essere comune (cioè presa dalla stessa fonte di energia) perchè ci serve la massa comune, altrimenti, le letture dei sensori non funzionerà e si avranno anche un sacco di altri problemi.

Componenti necessari
NOTA: lista provvisoria
  • Display Nokia 6100 LCD
    Diverse resistenze da 10kohm (una per ogni sensore tachimetrico delle ventoline, due per l'encoder, etc
    Connettori da 3 pin per ventole e varie
    basetta millefori o circuito stampato dedicato
    Diversi optoisolatori, transistor e mosfet (uno per ogni ventola e relè da pilotare)
Foto dimostratica con componenti di prova
Foto dimostratica con componenti di prova

Re: Rheobus con arduino

Inviato: 13 giu 2011 04:06
da master_of_mouse
Qui inserirò i codici da usare come software dell'Arduino (Sketch) definitivi o i singoli moduli

Re: Rheobus con arduino

Inviato: 13 giu 2011 04:09
da master_of_mouse
Qui inserirò i codici trovati sparsi qua e la da analizzare ed adattare allo scopo


Tratto da: Arduino Malaysia Forum

Codice: Seleziona tutto

    /*

    This sketch use PID controller to control PC fan speed and display result on a LCD.
    Setpoint for speed is read from a potentiometer. Data also send thru serial to PC
    running a real-time graph under Processing software.

    Author - Bro_Az August 2010.

      The circuit:
    * LCD RS pin to digital pin 7
    * LCD Enable pin to digital pin 6
    * LCD D4 pin to digital pin 5
    * LCD D5 pin to digital pin 4
    * LCD D6 pin to digital pin 3
    * LCD D7 pin to digital pin 2
    * ends to +5V and ground
    * 10k pot wiper to LCD VO pin (pin 3)

    */

    #include <LiquidCrystal.h>

    // If this is defined it prints out the FPS that we can send a
    // complete set of data over the serial port.
    //#define CHECK_FPS
     
    int tachPin = 8;   // fan tachometer connected to digital pin 8
    int fanPin = 11;  // fan drive connected to digital pin 11
    int sensorPin = 0; // analog input 0 for the potentiometer

    int sensorValue;  // variable to store the value coming from the sensor
    unsigned long duration; // time duration between tachometer pulses
    int max_rpm=4800; // max rpm at 100% PWM output
    int setpoint; // setpoint in %
    int speed; // fan speed in %
    float rpm; // fan speed in RPM

    int error;
    int last_error=0;
    int diff;
    float integ=0;
    float kp=1.0; // proportional gain
    float ki=0.5; // integral gain
    float kd=0.05; // derivative gain
    int out; // PID controller output

    boolean auto_manual=1; // setpoint manual or from pot
    int manual_setpoint=77;
    int sampletime=40; // Number of sample to average-out sampling values
    unsigned long val; // Working variable to hold the accumulated value

    unsigned int an0=0; // Variables for sending data to PC
    unsigned int an1=0;
    unsigned int an2=0;
    unsigned int an3=0;
    unsigned int an4=0;
    unsigned int an5=0;
    unsigned int offset=2;


    // initialize the LCD library routine with the numbers of the interface pins
    LiquidCrystal lcd(7, 6, 5, 4, 3, 2);

    void setup() {
    lcd.begin(16, 2); // set up the LCD's number of rows and columns:
    digitalWrite(tachPin, HIGH);  // turn on pull-up resistor
    Serial.begin(9600); // Serial port baud rate
    }

    void loop() {
     
    unsigned int startTag = 0xDEAD;  // Analog port maxes at 1023 so this is a safe termination value
                                     // for sending values to PC.
    #ifdef CHECK_FPS 
      unsigned long startTime, endTime;
      startTime = millis();
    #endif

    val=0;

    for (int i=0;i<sampletime;i++) {
    sensorValue = analogRead(sensorPin); // Read the value from the pot. AnalogRead values go from 0 to 1023.
    val=val+sensorValue;
    }
    sensorValue=val/sampletime;

    if (auto_manual) {
    setpoint=float(sensorValue)*100/1024;  // convert to percentage
    }
    else {
    setpoint=manual_setpoint;
    }

    duration=0;

    for (int i = 0; i < sampletime; i++) { // Average out pulseIn time reading in microseconds
        duration = duration+pulseIn(tachPin, HIGH);   
    }
       
        rpm=600000000/float(duration); // in RPM
        speed=rpm/max_rpm*100; // convert to percentage
        error=setpoint-speed;
        diff=error-last_error;
        integ=integ+error;
        out=kp*error+ki*integ+kd*diff;
       
        if (out<0) {out=0;integ=0;} //min limit, anti-reset wind-up
        if (out>255) {out=255;integ=integ-error;} //max limit, anti-reset wind-up
        analogWrite(fanPin, out);  // analogWrite values from 0 to 255, PWM output
             
        lcd.setCursor(0, 0); // Set for first line
        lcd.print(int(rpm)); // displays RPM value
        lcd.print(" RPM CO=");
        lcd.print(out);// displays Controller Output value
        lcd.print("   ");
       
        lcd.setCursor(0, 1); //set for second line
        lcd.print("SP=");
        lcd.print(setpoint);// displays setpoint value
        lcd.print("% ");
        lcd.print("PV=");// displays PV value
        lcd.print(speed);
        lcd.print("%   ");     
       
        if (auto_manual) { // if set-point in Auto, display "A"
          lcd.setCursor(15, 1);
          lcd.print("A");
         }
        else {
         lcd.setCursor(15, 1);// else display "M" for Manual
          lcd.print("M");
         }
       
        an0=setpoint*9+offset; // scaling for graph on PC
        an1=speed*9+offset;
        an2=out*3+offset;
       
      Serial.write( (unsigned byte*)&startTag, 2); // Send serial data to PC
      Serial.write((unsigned byte*)&an0, 2);
      Serial.write((unsigned byte*)&an1, 2);
      Serial.write((unsigned byte*)&an2, 2);
      Serial.write((unsigned byte*)&an3, 2);
      Serial.write((unsigned byte*)&an4, 2);
      Serial.write((unsigned byte*)&an5, 2);
     
    #ifdef CHECK_FPS 
      endTime = millis();
      Serial.print(" - FPS: ");
      Serial.println(1.f / (endTime-startTime) * 1000);
    #endif
    }

Re: Rheobus con arduino

Inviato: 13 giu 2011 08:44
da master_of_mouse
Codice diviso a seconda della funzione che voglio ottenere

Per leggere 6 temperature

Codice: Seleziona tutto

#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(32, 30, 28, 26, 24, 22);

#define LM35_TEMP0 0 // Pin analogico 0
int TEMP0; // valore di tensione letto dal pin OUT del sensore
#define LM35_TEMP1 1 // Pin analogico 1
int TEMP1; // valore di tensione letto dal pin OUT del sensore
#define LM35_TEMP2 2 // Pin analogico 2
int TEMP2; // valore di tensione letto dal pin OUT del sensore
#define LM35_TEMP3 3 // Pin analogico 3
int TEMP3; // valore di tensione letto dal pin OUT del sensore
#define LM35_TEMP4 4 // Pin analogico 4
int TEMP4; // valore di tensione letto dal pin OUT del sensore
#define LM35_TEMP5 5 // Pin analogico 5
int TEMP5; // valore di tensione letto dal pin OUT del sensore


void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(20, 2);
  // Print a message to the LCD.
  lcd.print("Temp1 Temp2 Temp3");
}

void loop() {
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0,1);
  float TEMP0;
  TEMP0 = (float)(5.0*analogRead(LM35_TEMP0)*100.0)/1024.0;
  lcd.print(" ");
  lcd.print(TEMP0,1);
  float TEMP1;
  TEMP1 = (float)(5.0*analogRead(LM35_TEMP1)*100.0)/1024.0;
  lcd.print(" ");
  lcd.print(TEMP1,1);
  float TEMP2;
  TEMP2 = (float)(5.0*analogRead(LM35_TEMP2)*100.0)/1024.0;
  lcd.print(" ");
  lcd.print(TEMP2,1);
  float TEMP3;
  TEMP3 = (float)(5.0*analogRead(LM35_TEMP3)*100.0)/1024.0;
  lcd.print(" ");
  lcd.print(TEMP3,1);
  float TEMP4;
  TEMP4 = (float)(5.0*analogRead(LM35_TEMP4)*100.0)/1024.0;
  lcd.print(" ");
  lcd.print(TEMP4,1);
  float TEMP5;
  TEMP5 = (float)(5.0*analogRead(LM35_TEMP5)*100.0)/1024.0;
  lcd.print(" ");
  lcd.print(TEMP5,1);
  delay(1000);
 }
Per leggere 6 segnali tachimetrici

Codice: Seleziona tutto

#include <LiquidCrystal.h>

int FANsensor0 = 48;   // fan tachometer connected to digital pin 48
int FANsensor1 = 49;   // fan tachometer connected to digital pin 49
int FANsensor2 = 50;   // fan tachometer connected to digital pin 50
int FANsensor3 = 51;   // fan tachometer connected to digital pin 51
int FANsensor4 = 52;   // fan tachometer connected to digital pin 52
int FANsensor5 = 53;   // fan tachometer connected to digital pin 53
unsigned long FANsignal0; // time duration between tachometer pulses
unsigned long FANsignal1; // time duration between tachometer pulses
unsigned long FANsignal2; // time duration between tachometer pulses
unsigned long FANsignal3; // time duration between tachometer pulses
unsigned long FANsignal4; // time duration between tachometer pulses
unsigned long FANsignal5; // time duration between tachometer pulses
float RPM0; // fan speed in RPM
float RPM1; // fan speed in RPM
float RPM2; // fan speed in RPM
float RPM3; // fan speed in RPM
float RPM4; // fan speed in RPM
float RPM5; // fan speed in RPM
int sampletime=1; // Number of sample to average-out sampling values

// initialize the LCD library routine with the numbers of the interface pins
LiquidCrystal lcd(32, 30, 28, 26, 24, 22);

void setup() {
lcd.begin(20, 2); // set up the LCD's number of rows and columns:
digitalWrite(FANsensor0, HIGH);  // turn on pull-up resistor
digitalWrite(FANsensor1, HIGH);  // turn on pull-up resistor
digitalWrite(FANsensor2, HIGH);  // turn on pull-up resistor
digitalWrite(FANsensor3, HIGH);  // turn on pull-up resistor
digitalWrite(FANsensor4, HIGH);  // turn on pull-up resistor
digitalWrite(FANsensor5, HIGH);  // turn on pull-up resistor
}

void loop() {

FANsignal0=0;
FANsignal1=0;
FANsignal2=0;
FANsignal3=0;
FANsignal4=0;
FANsignal5=0;

for (int i = 0; i < sampletime; i++) { // Average out pulseIn time reading in microseconds
FANsignal0 = FANsignal0+pulseIn(FANsensor0, HIGH);
}

for (int i = 0; i < sampletime; i++) { // Average out pulseIn time reading in microseconds
FANsignal1 = FANsignal1+pulseIn(FANsensor1, HIGH);
}

for (int i = 0; i < sampletime; i++) { // Average out pulseIn time reading in microseconds
FANsignal2 = FANsignal2+pulseIn(FANsensor2, HIGH);
}

for (int i = 0; i < sampletime; i++) { // Average out pulseIn time reading in microseconds
FANsignal3 = FANsignal3+pulseIn(FANsensor3, HIGH);
}

for (int i = 0; i < sampletime; i++) { // Average out pulseIn time reading in microseconds
FANsignal4 = FANsignal4+pulseIn(FANsensor4, HIGH);
}

for (int i = 0; i < sampletime; i++) { // Average out pulseIn time reading in microseconds
FANsignal5 = FANsignal5+pulseIn(FANsensor5, HIGH);
}

lcd.clear();
lcd.setCursor(0, 0); // Set for first line
lcd.print("RPM");
RPM0=(600000000/float(FANsignal0))/40; // in RPM
lcd.print(int(RPM0)); // displays RPM value
lcd.setCursor(7, 0); // Set for first line
lcd.print("RPM");
RPM1=(600000000/float(FANsignal1))/40; // in RPM
lcd.print(int(RPM1)); // displays RPM value
lcd.setCursor(14, 0); // Set for first line
lcd.print("RPM");
RPM2=(600000000/float(FANsignal2))/40; // in RPM
lcd.print(int(RPM2)); // displays RPM value
lcd.setCursor(0, 1); // Set for first line
lcd.print("RPM");
RPM3=(600000000/float(FANsignal3))/40; // in RPM
lcd.print(int(RPM3)); // displays RPM value
lcd.setCursor(7, 1); // Set for first line
lcd.print("RPM");
RPM4=(600000000/float(FANsignal4))/40; // in RPM
lcd.print(int(RPM4)); // displays RPM value
lcd.setCursor(14, 1); // Set for first line
lcd.print("RPM");
RPM5=(600000000/float(FANsignal5))/40; // in RPM
lcd.print(int(RPM5)); // displays RPM value
}

Re: Rheobus con arduino

Inviato: 07 giu 2016 05:26
da najatuw4646
Average out pulseIn time reading in microseconds FANsignal.

online casino