interface c# / arduino

Bonjour,

Je travail sur un logger qui enregistre les données d'un capteur et les stockent sur une carte SD.

L'idée c'est de faire un petit programme en C# pour récupérer les données de la carte SD sans avoir a la sortir a chaque fois qu'on veut récupérer les données.

Du coup je me demandais s'il y a avait un moyen d'envoyer directement les commandes comme sd.open() par exemple ?

où est ce qu'on est obligé de mettre des Serial.read() dans la boucle de l'arduino pour voir ce que le programme en C# envoie sur le port série et faire une méthode correspondant a l'action désirée ?

Si on pouvait envoyer directement la commande depuis le C# vers l'arduino ça m'arrangerait ca je suis sur une carte pro mini et mon sketch frôle les 80% de la mémoire et les problèmes de stabilité qui vont avec. Du coup rajouter du code dans le sketch c'est compliqué

Merci d'avance

Bonjour
Si dans le code sketch de l'arduino rien n'est prévu pour cette tache, il n'y comprendra pas grand chose.
Il faut a minima ajouter quelques fonctions à ce sketch,

Lecture du port série pour intercepter la commande ,
et le déversement du contenu de la carte sd vers ce dernier, avec un contrôle de checksum.

20% restant sur un pro mini c'est 6KB de code, c'est suffisant.

Le croquis utilise 25202 octets (82%) de l'espace de stockage de programmes. Le maximum est de 30720 octets.
Les variables globales utilisent 1650 octets (80%) de mémoire dynamique, ce qui laisse 398 octets pour les variables locales. Le maximum est de 2048 octets.
La mémoire disponible faible, des problèmes de stabilité pourraient survenir.

voici ce qu'il me met quand je compile le sketch que j'avais codé à la base. Je l'ai allégé en virant les serial.print qui me servaient juste de retour pour savoir si tout allait bien.
Et quand je fait tourner le programme alors qu'il m'a mis ce message ... j'ai bien des problèmes de stabilité. Il fait 1 ou 2 boucles et plus rien.

Je vais regarder la piste du checksum, parce je voyais plutot faire écrire le fichier ligne par ligne a l'arduino dans le port série, et faire lire le port série a l'application c#.

ton systeme est conecté continuellement sur un ordinateur ( port serie) ou non?

Tu fais un datalogguer, le plus simple en effet est d'envoyer par le port serie toutes les données que tu as besoin.

Je te pose la question, si ton arduino est continuellement connecté a un ordinateur, je ne connais pas la finalité, mais pourquoi utilisé une carte SD?
pourquoi ne pas envoyer les données necessaire sur ton application en C# puis sauvegarder les données sur une base de données ou autre fichier?

Non le sytème est autonome, il sera posé sur un appareil qui est transporté et il a pour but d'enregistrer l'accélération que subit l'appareil sur lequel il est posé.

c'est pourquoi je stock ça sur une carte SD.

le programme en c# est juste là pour récupérer les données de la carte SD sans avoir a la sortir physiquement tous les jours.

Salut

Les variables globales utilisent 1650 octets (80%) de mémoire dynamique, ce qui laisse 398 octets pour les variables locales. Le maximum est de 2048 octets.
La mémoire disponible faible, des problèmes de stabilité pourraient survenir.

Les 80% représentent les variables globales, rien à voir avec le code. En quantité de code tu peux bourrer à 100%, cela ne générera aucun plantage.
Par contre, 398 octets de RAM restante peuvent poser problème car c'est là que se trouve la pile d'appels, et les variables locales.

Le message "des problèmes de stabilité pourraient survenir" n'est pas forcément alarmant. Cela peut très bien passer. Je développe en ce moment un logiciel qui me laisse 461 octets de RAM libre. Cela tourne parfaitement bien, pendant des heures.
J'empile au maximum 40 octets sur trois niveaux d'appels maximum.

S'il y a des problèmes de stabilité, il faut fouiller dans les variables locales, celles qui sont déclarées dans les fonctions.
Regarder s'il y a des tableaux ou des structures de taille importante.

Si une fonction A() appelle une fonction B() qui appelle une fonction C() et que ces fonctions déclarent chacune 100 octets de variables locales, quant la fonction C() s'exécute, il y a empilement de 300 octets en tout, plus les adresses de retour pour les fonctions A() et B().

Éviter d'empiler des appels de fonctions peut donc aussi aider.

2ko de RAM ce n'est pas grand chose smiley-confuse:

@+

j'ai un tableau de char pour créer un nom de fichier d'après une variable, mais j'ai essayé en le virant, je gagne pas 1%

voici mon code, j'ai essaye d'alléger au maximum les variables utilisées, j'arrive a 69%

Je testerais ce soir, mais en tout cas il compile sans problème !

#include <Wire.h>
#include <LSM303.h>
#include <SFE_BMP180.h>
#include <SD.h>
#include <SPI.h>
#include <stdio.h>
#include <DS1302.h>
File myFile;

DS1302 rtc(2, 3, 4);


double T,P,p0,a;
float maxz=0;
float minz=0;
float maxx=0;
float minx=0;
float maxy=0;
float miny=0;
int counter=0;
unsigned long startMillis;  //some global variables available anywhere in the program
unsigned long currentMillis;
unsigned long counterloop;
unsigned long interval1;
unsigned long interval2;
unsigned long interval3;
String bla;
 char filename[] = "00000000.txt";


LSM303 compass;
SFE_BMP180 pressure;
Time now = rtc.time(); 


//fonction pour la cération du nom du fichier correspondant à la date du jour
void getFilename(char *filename,Time now) {
    int year = now.yr; int month = now.mon; int day = now.date;
    filename[0] = '2';
    filename[1] = '0';
    filename[2] = year%10 + '0';
    filename[3] = year%10 + '0';
    filename[4] = month/10 + '0';
    filename[5] = month%10 + '0';
    filename[6] = day/10 + '0';
    filename[7] = day%10 + '0';
    filename[8] = '.';
    filename[9] = 'T';
    filename[10] = 'X';
    filename[11] = 'T';
    return;
  }


void setup()
{
 
  Serial.begin(9600);
  Wire.begin();
  compass.init();
  pressure.begin();
  compass.enableDefault();  



 getFilename(filename,now); //appel de la fonction
 
  if (!SD.begin(8)) {
    Serial.println("initialization failed!");
    //while (1);
  }
  String Entete="Xmin  Xmax  Ymin  Ymax  Zmin  Zmax  Température  Pression Date Heure";
  
 if (SD.exists(String(filename))) 
 {  } 
 else {

    myFile = SD.open(filename, FILE_WRITE);
  myFile.println(Entete);
  myFile.close();
  }
}


void loop()
{
  currentMillis=millis();
  now = rtc.time();
 
  //getFilename(filename);
  
  if (currentMillis >=interval1)
  {
    pressure.startTemperature();
    interval1=2000*(counterloop+1);
    interval2=2000*(counterloop)+10;
  }
  
  if (currentMillis >=interval2)
  {
    pressure.getTemperature(T);
    pressure.startPressure(3);
   
    interval2=2000*(counterloop+1)+10;
    interval3=2000*(counterloop)+51;
      
  }

   if ( currentMillis >=interval3)
  {
     
    
     pressure.getPressure(P,T);
     

     bla+=String(maxx);
     bla+=" ";

     bla+=String(minx);
     bla+=" ";

     bla+=String(maxy);
     bla+=" ";

     bla+=String(miny);
     bla+=" ";

     bla+=String(maxz);
     bla+=" ";

     bla+=String(minz);
     bla+=" ";
     bla+= String(T,2);
     bla+=" ";
     bla+=String(P,1);
     bla+=" ";
     bla+=String(now.date);
     bla+=" ";
     bla+=now.hr+String(":")+now.min+String(":")+now.sec;

     myFile = SD.open(filename, FILE_WRITE);
     myFile.println(bla);
     Serial.println(bla);
     myFile.close();
     

     bla="";
  counter=0;
  maxz=0;
  maxx=0;
  maxy=0;
  minx=0;
  miny=0;
  minz=0;

     
     interval3=2000*(counterloop+1)+10;
     counterloop++;
  }


  compass.read();
  if (compass.a.z*0.122/1000.0>maxz)
  { maxz=compass.a.z*0.122/1000.0;}
    if (compass.a.x*0.122/1000.0>maxx)
  { maxx=compass.a.x*0.122/1000.0;}
    if (compass.a.y*0.122/1000.0>maxy)
  { maxy=compass.a.y*0.122/1000.0;}
    if (compass.a.z*0.122/1000.0<minz)
  { minz=compass.a.z*0.122/1000.0;}
    if (compass.a.x*0.122/1000.0<minx)
  { minx=compass.a.x*0.122/1000.0;}
    if (compass.a.y*0.122/1000.0<miny)
  { miny=compass.a.y*0.122/1000.0;}
  counter++;
  
  
 }

Le problème d'arduino quand on veux faire des systèmes "critiques" en terme de mémoire en utilisant les divers librairies, c'est qu'on ne maîtrise pas l'optimisation.

Mais rien n’empêche, d'y inclure de l'assembleur par exemple.

Je me souviens, avoir "porté" une de mes réalisations développée sous codevision vers un sketch arduino pour évaluation. J'avais augmenté la consommation de ram de 25%...

Juste pour dire que l'optimisation ne s’arrête pas à enlever ici et là quelques codes inutile mais de bien penser à l'ensemble et utiliser du code moins gourmand.

Effectivement, il n'y a pas beaucoup de variables locales dans ce code, zéro même, mais il y a celles des fonctions et méthodes des bibliothèques ...

@+