Contrôle de port de la carte Arduino depuis PC Linaro en C

Bonjour à tous,

Je suis débutant avec Arduino, pour un projet de domotique j'aimerais piloter les port logique d'une carte mega 2560 (pour piloter un moteur) depuis un PC ainsi que récupérer les valeurs de capteurs analogiques branchés sur les ports analogique de la carte depuis un PC linux (Lina 13.04) via USB en code C mais je ne sais pas trop comment aborder la communication USB (Arduino est nouveau pour moi)

merci d'avance

Up

La carte Arduino depuis le PC est vue comme un port série identifié sous Linux comme /dev/ttyUSB0 ou approchant. C'est le nom qui apparaît dans l'IDE arduino. Sinon tu ouvres une console juste après avoir branché la carte arduino et tu fais un dmesg |tail et tu devrais voir quelque chose comme ça:

[12088.676111] usb 4-2: new full-speed USB device number 10 using ohci_hcd
[12088.860510] ftdi_sio 4-2:1.0: FTDI USB Serial Device converter detected
[12088.860588] usb 4-2: Detected FT232RL
[12088.860594] usb 4-2: Number of endpoints 2
[12088.860600] usb 4-2: Endpoint 1 MaxPacketSize 64
[12088.860606] usb 4-2: Endpoint 2 MaxPacketSize 64
[12088.860611] usb 4-2: Setting MaxPacketSize 64
[12088.864628] usb 4-2: FTDI USB Serial Device converter now attached to ttyUSB0

Pour communiquer avec la carte, depuis n'importe quel langage de programmation, il suffit d'ouvrir le port en question est de dialoguer avec la carte suivant le protocole que tu auras défini.

J'ai réussi à écrire un code de communication, finalement en Python mais dans le code Arduino il y a des conditions qui tourne en permanence indépendamment du port série ces conditions mette en route ou non des relais suivant la valeur d'un capteur analogique mais avec mon code python je dois absolument pouvoir éteinte et allumer les relais, les conditions qui tourne en permanence prennent la main sur les instructions série.
code Python :

#!/usr/bin/python
import serial, time, MySQLdb
arduino = serial.Serial('/dev/ttyACM0', 9600, timeout=None)
time.sleep(1) 
print("initialisation...")
arduino.open()

arduino.write('H') 
time.sleep(2) 
reponse = arduino.readline()
print reponse
time.sleep(2) 

arduino.write('L') 
time.sleep(2) 
arduino.close() 

db = MySQLdb.connect("localhost","root","mot_de_passe","composant_live" )


cursor = db.cursor()


sql = "UPDATE capteurs_solaires SET angle_incidence=%s WHERE id=1" % \
             (reponse )

try:

   cursor.execute(sql)

   db.commit()
except:

   db.rollback()


db.close()

code Arduino :

#define BAUDRATE 9600
 
 
char val = ' ';
 
void setup() {
 
 
Serial.begin(BAUDRATE);
 

 
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
}
 
void loop() {
  int angle_panneaux = analogRead(A0);
  int en_com;
if (Serial.available()) {
 en_com = 1;
val = Serial.read();
 
if (val == 'H') {
 en_com = 1;
 
digitalWrite(8,HIGH);
digitalWrite(9,HIGH);
digitalWrite(10,HIGH);
 Serial.println(angle_panneaux);

 Serial.println(en_com);
en_com = 0;
} else if (val == 'L') {
  en_com = 1;
digitalWrite(8,LOW);
digitalWrite(9,LOW);
digitalWrite(10,LOW);
 Serial.println(angle_panneaux);
 Serial.println(en_com);
en_com = 0;
}
}

  if(en_com == 0){
if(angle_panneaux < 500){
digitalWrite(8,HIGH);
digitalWrite(9,HIGH);
digitalWrite(10,HIGH);
   
}

if(angle_panneaux > 500){
digitalWrite(8,LOW);
digitalWrite(9,LOW);
digitalWrite(10,LOW);
   
}
}
}

Ton code arduino fait ce que tu l'as programmé à faire.
Dans loop tu as mis à la suite la réception des messages par la liaison série et les commandes automatiques donc il les exécute en séquence.

Si tu veux un comportement différent, il faut modifier ton programme.
En premier lieu, si tu veux avoir 2 comportement différents, automatique et manuel, il faut définir les conditions de passage d'un mode à l'autre.
Il faut bien détailler par écrit ce que doit faire ton programme:
Dans quel cas il est autonome, dans quel cas il est piloté par la liaison série.
Comment il passe d'autonome à piloté:
par une commande, laquelle?
automatiquement, dans quelle(s) condition(s) conditions extérieure, action sur un bouton, temporisation,....

Ensuite tu pourras réécrire ton programme pour qu'il fasse ce que tu veux.

j'ai reussie à faire un protocole avec mode manu et auto mais pour mon projet il faut que le code python du PC puisse envoyer des valeurs comme des températures vers l'arduino et que l'arduino puisse savoir a quoi correspondent c'est température genre température chaudière ou température chauffe eau mais mon programme actuelle ne peut envoyer une lettre vers l'arduino il faudrait une chaîne de caractère avec un code genre 22CE pour 22°C chauffe eau mais je suis débutant en C et Arduino et je sais pas comment faire

code python :

#!/usr/bin/python
import serial, time, MySQLdb
arduino = serial.Serial('/dev/ttyACM0', 9600, timeout=None)
time.sleep(1) 
arduino.open() 
arduino.write('H') 
arduino.write('G')  
reponse = arduino.readline()


db = MySQLdb.connect("localhost","root","mot_de_passe","composant_live" )


cursor = db.cursor()


sql = "UPDATE capteurs_solaires SET angle_incidence=%s WHERE id=1" % \
             (reponse )

try:

   cursor.execute(sql)

   db.commit()
except:

   db.rollback()


db.close()
arduino.close()

code Arduino :

#include <math.h>
//Liste des PIN
#define PIN_SENSOR_ANGLE A1
#define PIN_RELAY1 22
#define PIN_RELAY2 24
#define PIN_RELAY3 26

//allume les relais à partir angle=500 avec une hystérésis pour les parasites
#define ANGLE_CHANGE_UP 439
#define ANGLE_CHANGE_DOWN 447

//Com série
#define BAUDRATE 9600

//Mode de fonctionnement
#define MODE_AUTO 1
#define MODE_MANU 2
#define DEFAULT_MODE MODE_AUTO

float Temp=0;

void setup(){
	long previousMillis=0; // will store last time LED was updated
	
	// the follow variables is a long because the time, measured in miliseconds,
	// will quickly become a bigger number than can be stored in an int.
	long interval=5000;           // interval at which to blink (milliseconds)
	unsigned long currentMillis = millis();
	
	pinMode(PIN_RELAY1, OUTPUT);
	pinMode(PIN_RELAY2, OUTPUT);
	pinMode(PIN_RELAY3, OUTPUT);
	
	digitalWrite(PIN_RELAY1, LOW);
	
	//état des relais pas défaut
	if(currentMillis - previousMillis > interval) {
		// save the last time you blinked the LED
		previousMillis = currentMillis;    
		digitalWrite(PIN_RELAY1, HIGH); 
	}
	digitalWrite(PIN_RELAY2, LOW);
	digitalWrite(PIN_RELAY3, LOW);
	
	//initialise le port com
	Serial.begin(BAUDRATE);
}

void loop(){
	//var et init var
	int angle;
	bool relayCmd=false; //donne l'ordre activer/désactiver les rélais
	bool relayState=false; //indique l'états des rélais
	unsigned char mode=DEFAULT_MODE;
	
	//boucle principale
	while(true){
		//lecture des capteurs
		angle=analogRead(PIN_SENSOR_ANGLE);
		int RawADC;
                RawADC=analogRead(PIN_SENSOR_ANGLE);
		//communication et traitement
		if (Serial.available()) {
			char c=Serial.read();
			switch(c){
				case 'A': //mode auto
					mode=MODE_AUTO;
					break;
				case 'H': //activation des relais + mode manu
					relayCmd=true;
					mode=MODE_MANU;
					break;
				case 'L': //activation des relais + mode manu
					relayCmd=false;
					mode=MODE_MANU;
					break;
				case '22': //demande de lecture de l'angle
                                        Serial.print("Angle: ");
                                        Serial.println(angle);
                                        Temp = log(((10240000/RawADC) - 10000));
                                        Temp = 1 / (0.001129148 + (0.000234125 * Temp) + (0.0000000876741 * Temp * Temp * Temp));
                                        Temp = Temp - 273.15;           // Convert Kelvin to Celcius
                                        Serial.print("Celsius: ");
					Serial.println(Temp);
					break;
			}
		}
	
		//calcul et traitement
		if(mode==MODE_AUTO){
			if (angle>ANGLE_CHANGE_UP)
				relayCmd=true;
			if (angle<ANGLE_CHANGE_DOWN)
				relayCmd=false;
		}
		
		//exécution des ordres
		if (relayCmd==true && relayState==false){ //front montant
			digitalWrite(PIN_RELAY1,HIGH);
			digitalWrite(PIN_RELAY2,HIGH);
			digitalWrite(PIN_RELAY3,HIGH);
			relayState=true;
		}
		
		if (relayCmd==false && relayState==true){ //front descendant
			digitalWrite(PIN_RELAY1,LOW);
			digitalWrite(PIN_RELAY2,LOW);
			digitalWrite(PIN_RELAY3,LOW);
			relayState=false;
		}
	}
}

up