Distributeur de médicament autonome

Portrait de Brandon

Bonjour bonjour !

Au sein de mon lycée, je dois réaliser un projet pour le Bac (coefficient 12, disons que c'est du sérieux ^^) avec un choix libre. Personnellement, j'ai eut l'idée de fabriquer un distributeur de médicament autonome, à destination des personnes âgées. Le but serait que, à des jours et heures programmés, on distribue un traitement pré-stocké, et on prévoit un envoie de sms à une personne si le traitement n'est pas pris.

Je vais en rester à cette fonction car c'est ici que je suis actuellement bloqué. J'ai choisit d'utiliser un shield GPRS pour envoyer un SMS (aucun problème de ce coté là). J'utilise un afficher LCD (de type 20x4) pour afficher les informations de programmations des horaires, complété par un module I2C. J'utilise avec ceci un clavier matriciel 16 touches. Je bosse actuellement sur le programme mais j'éprouve quelques difficultés....

Déjà, comment faire en sorte qu'une fois l'action d'une condition finie, on garde les informations choisis, on quitte la condition et en lance une deuxième ?

Exemple: On appuit sur la touche A et le programme pour les jours se lance, on garde les informations. On sors de cette boucle (tout en gardant "en mémoire" les choix effectués). On appuis sur la touche B et le programme pour les heures se lance, on garde les informations aussi (IDEM, on garde les choix). On appuis sur la touche C et le programme pour le numéro se lance (IDEM...).

Comment récupérer les informations du choix du jours et des heures pour les garder dans le programme de la distribution ? Comment, une fois le numéro de téléphone tapé, l'ajouter au programme de l'envoi du SMS ?

Je vous remercie d'avance pour un début d'idée ^^ Si vous souhaitez je peux poster les bribes de programmes que j'ai déjà tapé.

Brandon :-)

Portrait de Alex

Salut,

Je ne comprends pas très bien ta question, est-ce que tu peux faire un diagramme avec blocs?

Je pourrais ensuite te rédiger et t'expliquer le code.

Portrait de Brandon

Voilà le diagramme bloc du programme que je souhaite réaliser pour l'afficheur LCD (en vert sont les commentaires).

capture_decran_2016-02-20_a_21.59.04.png

Le problème est donc de garder en mémoire les informations choisis (les dates, les heures, le(s) numéro(s)) afin de les intégrer dans le programme principal (comprenant les commandes du shield GPRS, des moteurs à actionner pour la distribution, des alertes à activer si nécessaire, etc…).
Si quelque chose n’est pas clair, n’hésitez pas à me poser des questions, et si vous souhaitez voir les programmes que j’ai déjà tapé, n’hésitez pas à me demander.

Si vous souhaiter je pourrais poster le bloc de mon projet au complet (avec toutes les fonctions)...
Et Merci !!!
Brandon :-)

Portrait de Cédric29

Salut.

Il semblerait possible de stocker des variables sur l'eeprom de l'arduino, sinon tu peux le faire sur une carte sd.

Il va te falloir une horloge RTC.

Portrait de Brandon

Salut hcfroid !

Le fait de stocker des variables m'était déjà venu à l'idée, mais qu'entends-tu par cela ? Une variable pour un jour ? Comment ça sur une carte SD ?

MERCI pour l'idée de l'horloge RTC, je ne connaissais pas ! Je pense que je vais investir parce qu'il semble convenir parfaitement à la tâche que je souhaite réaliser. Le seul hic est que j'utilise déjà l'I2C de l'Arduino avec le LCD, je vais donc devoir penser à faire communiquer 2 Arduino en série entre eux... :/

Mais vraiment merci, je vais essayer de familiariser avec, le temps de me le procurer. D'ailleurs que penses-tu du RTC-1307 ? C'est un bon choix ?

Brandon :-)

Portrait de Cédric29

Il existe des shields ou tu ajoutes un carte sd.
Imagine cette methode:
A chaque demarrage de l'arduino, tu vas chercher sur carte sd ou eeprom s'il existe une variable numero_telephonne.si abscente ou =0,tu demarres fonction d'acquisition par le lcd,quand tu as le numero de tel, tu l'enregistres sur sd ou eeprom .
si cette variable est deja stocké sur l'eeprom ou carte sd, lecture et attribution de la valeur stocke a la variable ds l'arduino.
Ex: num_tel_arduino=num_tel_dans l'eeprom;

Tu fais la meme chose avec le traitement.si traitement=0 ou absent, demmarage fonction d'acquisition par lcd ,avec variable nombre de jours, jours,heure .

Grosso merdo t as du boulot

Portrait de Brandon

Ah ok d'accord, je ne voyais pas cela comme ça !

Mais j'admet que l'idée est vraiment pertinente, au lieu me faire iech à vouloir retranscrire le numéro dans un autre programme, allez récupérer ce même numéro stocké. Fallait y penser, je vais réfléchir comment le mettre en oeuvre...

Quand tu dis traitement=0, c'est quand il n'a pas été stocké, ou pas distribué ?

Pffff plus je fais des découvertes qui me permettent d'avancer, plus ça rajoute du boulot lol,

merci

Portrait de Cédric29

Oui traitement=0 veut dire qu il n y a eu aucune saisie de jour'd'heure ,de duree .

c est juste un exemple

Portrait de Brandon

D'accord, l'idée est très bonne et je vais essayer de préciser tout ça, merci

Portrait de Cédric29

Commence par enregistrer une variable sur l'eeprom puis essaye d'aller la lire,puis une 2 ieme etc

je dis eeprom, mais je ne sais pas si c'est le meilleur choix ,renseigne toi sur sa taille .

Portrait de Brandon

D'accord, y aller "à tâtons" en quelques sortes. Je viens de me renseigner et l'eeprom de l'Arduino est de 512 octet, c'est certes peu mais je pense que pour des variables comme un numéro de téléphone, ou des heures, ça devrait suffire non ?

Portrait de Alex

Je rejoins l'idée du module RTC, par contre si tu n'as pas trop de numéro à enregistrer, le lecteur SD n'est peut-être pas nécessaire.

Portrait de Brandon

Salut Alex ! Ok pour le RTC, pour les numéros il y en aura un, peut être 2 mais c'est VRAIMENT si je finis mon programme en avance... Ce qui ne risque pas d'etre le cas ^^

Par contre je cherche un programme pour l'EEPROM mais j'ai toujours des erreurs... une idée ? :/

De plus, dans mon programme pour le GPRS je dois mettre du type "+336********" mais je ne peux pas mettre de +, comment faire ? :/

capture_decran_2016-02-22_a_20.25.08.png

Portrait de Cédric29

perso je distingue  pas grand chose .Copie nous ton code.

Portrait de Brandon

Ah ok excuse:

#include <EEPROM.h> //Librairie pour accéder à la mémoire morte

void setup() {
  Serial.begin(9600);

  long numero= 651109561; //Numéro bidon
  EEPROM.put(0, numero); //Ecriture du numéro à l'adresse 1
}

void loop() {
  long numero= 651109561;
  EEPROM.get(0, numero);
  Serial.println(numero);
  delay(500);
}

Portrait de Brandon

Je n'ai plus d'erreurs avec ce programme, l'utilisation du long convient et le chiffre n'est pas trop gros.

Je me permet de poster le programme de mon LCD pour intégrer le numéro, que vous me donniez vos avis dessus car je ne suis vraiment sûr de rien pour l'EEPROM. Le reste est bon, je l'ai testé.

#include <Wire.h>
#include "CLCD.h"
CLCD lcd(0x27,20,4);

#include <Keypad.h> // inclusion de la librairie pour clavier matriciel

//--- Constantes utilisées avec le clavier 4x4
const byte LIGNES = 4; // 4 lignes
const byte COLONNES = 4; // 3 colonnes

const int C4=2;//declaration constante de broche
const int C3=3; //declaration constante de broche
const int C2=4; //declaration constante de broche
const int C1=5; //declaration constante de broche
const int L4=A0; //declaration constante de broche
const int L3=A1; //declaration constante de broche
const int L2=A2; //declaration constante de broche
const int L1=A3; //declaration constante de broche

//--- Définition des touches
char touches[LIGNES][COLONNES] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};

// tableaux de lignes et colonnes
byte BrochesLignes[LIGNES] = {L1, L2, L3, L4}; //connexions utilisées pour les broches de lignes du clavier
byte BrochesColonnes[COLONNES] = {C1, C2, C3, C4}; //connexions utilisées pour les broches de colonnes du clavier

char touche; // variable de stockage valeur touche appuyée

// création d'un objet keypad = initialisation clavier
Keypad clavier = Keypad( makeKeymap(touches), BrochesLignes, BrochesColonnes, LIGNES, COLONNES );
// les broches de lignes sont automatiquement configurées en ENTREE avec pullup interne activé
// les broches de colonnes sont automatiquement configurées en SORTIE

void setup() {
  lcd.init();
  delay(10); //pause rapide pour initialisation
 
  lcd.backlight();
  lcd.print("   Bienvenue sur");
  lcd.setCursor(1,1);
  lcd.print("votre distributeur");
  lcd.setCursor(3, 0);
  lcd.print("1 pour commencer");
}

void loop() {
  touche=clavier.getKey();
  if(touche=='1');
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Tapez le numéro de");
    lcd.setCursor(1, 0);
    lcd.print("téléphone:");
    lcd.setCursor(2, 0);
    
    numero=(touche!= NO_KEY);
    lcd.print(numero);
    
    if(touche=='A');
    {
      EEPROM.put(numero)
    }
}
}

Portrait de Cédric29

voici un lien vers des fonctions pour enregistrer et lire des Variables long sur l'eeprom automatiquement.

http://playground.arduino.cc/Code/EEPROMReadWriteLong

essais de t'en inspirer , essaye le a part et bricole le pour qu'il te convienne

Portrait de Cédric29

<p>Re Je ne connais pas ce type de lcd jamais esayer encore. Dans ton programme je ne vois pas ou tu declares ta variable numero. Est ce qu'il est possible de recuperer la saisie du numero de telephone directement en variable 'long numero' ou alors tu ne peux la recuperer que chiffre par chiffre ?</p>

Portrait de Brandon

Hey !

Oui effectivement, je n'ai pas déclarer la variable "numero".

Pour le LCD, je te le conseil vivement; j'utilise un 20x4 avec un module I2C: 2 fils nécessaires (sans l'alim'), et il est simple d'utilisation niveau programme, avec la librairie !

Par contre je ne comprend pas ta question pour récupérer la saisie du numéro :/

Portrait de Brandon

Bonjour bonjour ! Je reviens vers vous aujourd'hui suite au programme que j'ai entamé aujourd'hui (continué plutôt). J'ai tenté d'enregistrer les infos des variables des jours dans une SD (1 pour LUNDI, 2 pour MARDI, etc...) et de les ajouter dans un bout de commande tiré d'un programme pour module RTC (le ds1307). Je vous le poste ici en espérant avoir vos avis, dites moi tout :-) Suis-je sur la bonne voie ?

(Par contre petit problème: Arduino me dit "La mémoire disponible faible, des problèmes de stabilité pourraient survenir.", comment puis-je contrer cela ? Faire des sous-programmes et les ajouter eux aussi dans la SD ?)

Merci et à très vite :)

#include "RTClib.h"
RTC_DS1307 RTC;

#include <Wire.h>
#include "CLCD.h"

#include <SPI.h>
#include <SD.h>
File fichierSD;

CLCD lcd(0x27,20,4);

#include <Keypad.h> // inclusion de la librairie pour clavier matriciel

//--- Constantes utilisées avec le clavier 3x4
const byte LIGNES = 4; // 4 lignes
const byte COLONNES = 4; // 3 colonnes

const int C4=2;//declaration constante de broche
const int C3=3; //declaration constante de broche
const int C2=4; //declaration constante de broche
const int C1=5; //declaration constante de broche
const int L4=A0; //declaration constante de broche
const int L3=A1; //declaration constante de broche
const int L2=A2; //declaration constante de broche
const int L1=A3; //declaration constante de broche

//--- Définition des touches
char touches[LIGNES][COLONNES] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};

// tableaux de lignes et colonnes
byte BrochesLignes[LIGNES] = {L1, L2, L3, L4}; //connexions utilisées pour les broches de lignes du clavier
byte BrochesColonnes[COLONNES] = {C1, C2, C3, C4}; //connexions utilisées pour les broches de colonnes du clavier

char touche; // variable de stockage valeur touche appuyée

// création d'un objet keypad = initialisation clavier
Keypad clavier = Keypad( makeKeymap(touches), BrochesLignes, BrochesColonnes, LIGNES, COLONNES );
// les broches de lignes sont automatiquement configurées en ENTREE avec pullup interne activé
// les broches de colonnes sont automatiquement configurées en SORTIE

void setup() {
 Serial.begin(57600);

 
//Initialisation de l'instance pour la SD
if(!SD.begin(4))
 {
   Serial.println(F("Initialisation impossible !"));
   return;
  }
  Serial.println(F("Initialisation OK"));

 
lcd.init();
delay(10);
// pause rapide pour laisser temps initialisation

lcd.backlight();
lcd.print("   Bienvenue sur");
lcd.setCursor(1, 1);
lcd.print("votre distributeur");
lcd.setCursor(3, 0);
lcd.print("V pour commencer");

delay(1000); // pause de 1 seconde
}

void loop() {
touche = clavier.getKey();
// Lecture de la touche appuyée
if (touche != NO_KEY)
{
  if (touche=='D')   
      // Si la touche D (v) a été tappée
  {
    if (touche != NO_KEY)
  {
    lcd.clear();
    lcd.setCursor(1, 0);
    lcd.print(" Vous allez debuter");
    lcd.setCursor(2,2);
    lcd.print("la configuration");
    
    delay(5000);
    lcd.clear();
    lcd.setCursor(0, 4);
    lcd.print("Quels jours");
    lcd.setCursor(1, 1);
    lcd.print("prenez-vous votre");
    lcd.setCursor(2, 3);
    lcd.print("traitement ?");
    
    delay(5000);
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("1-LUN");
    lcd.setCursor(1, 0);
    lcd.print("2-MAR");
    lcd.setCursor(2, 0);
    lcd.print("3-MER");
    lcd.setCursor(0, 6);
    lcd.print("4-JEU");
    lcd.setCursor(1, 6);
    lcd.print("5-VEN");
    lcd.setCursor(2, 6);
    lcd.print("6-SAM");
    lcd.setCursor(0, 12);
    lcd.print("7-DIM");
    lcd.setCursor(1, 12);
    lcd.print("#-EFFACE");
    lcd.setCursor(2, 12);
    lcd.print("*-SUITE");
    lcd.setCursor(3, 0);
    lcd.print("Choix:");
  }
    
    int LUNDI= '1';
    int MARDI= '2';
    int MERCREDI= '3';
    int JEUDI= '4';
    int VENDREDI= '5';
    int SAMEDI= '6';
    int DIMANCHE= '7';
    int EFFACER= '#';
    int SUITE= '*';
    
    if(touche=='1')
    {
      fichierSD = SD.open("distribLUNDI.log", FILE_WRITE);
      fichierSD.print("now.dayOfWeek() == 1");
      fichierSD.close();
    }
    
    if(touche=='2')
    {
      fichierSD = SD.open("distribMARDI.log", FILE_WRITE);
      fichierSD.print("now.dayOfWeek() == 2");
      fichierSD.close();
    }
    
    if(touche=='3')
    {
      fichierSD = SD.open("distribMERCREDI.log", FILE_WRITE);
      fichierSD.print("now.dayOfWeek() == 3");
      fichierSD.close();
    }
    
    if(touche=='4')
    {
      fichierSD = SD.open("distribJEUDI.log", FILE_WRITE);
      fichierSD.print("now.dayOfWeek() == 4");
      fichierSD.close();
    }
    
    if(touche=='5')
    {
      fichierSD = SD.open("distribVENDREDI.log", FILE_WRITE);
      fichierSD.print("now.dayOfWeek() == 5");
      fichierSD.close();
    }
    
    if(touche=='6')
    {
      fichierSD = SD.open("distribSAMEDI.log", FILE_WRITE);
      fichierSD.print("now.dayOfWeek() == 6");
      fichierSD.close();
    }
    
    if(touche=='7')
    {
      fichierSD = SD.open("distribDIMANCHE.log", FILE_WRITE);
      fichierSD.print("now.dayOfWeek() == 7");
      fichierSD.close();
    }
  }
}
}

Au fait, dans le loop je crains une petite chose: est-ce qu'en déclarant les touches 1 à 7 en variables pour lundi, à dimanche, cela ne va pas continuer à être le cas pour la suite du programme ?

Portrait de Brandon

Bonjour bonjour ! A l'approche de la fin d'année (et du bac), tout commence à s'activer. Et j'ai progressé (doucement) sur mon projet de distributeur autonome. Cependant j'ai toujours des difficultées, je re-sollicite votre aide.

J'ai réalisé l'interface globale sur mon LCD, le fait communiquer avec le clavier, etc. J'ai réussis à envoyer des SMS via le shield GPRS. Mais comme je l'ai dis, plusieurs difficultés apparaissent:

1) Lorsqu'on rentre une heure sur le clavier, je veux faire tourner un moteur à cette heure. Mais je ne parvient pas à enregistrer les heures et les adapter pour faire tourner mon moteur. Les enregistrer dans l'EEPROM ? Et comment ? Faire un autre système ? J'ai vu qu'il fallait utiliser un module d'horloge, est-ce nécessaire étant donné que j'utilise un shield GPRS ? On peut récupérer l'heure grâce à celui-ci non ?

2) De même qu'avant, je veux envoyer un SMS. Qui dit SMS dit numéro de téléphone... De même, suite au programme jours/heures je demande de taper le numéro. Mais comment l'enregistrer et le récupérer dans le programme permettant d'envoyer un SMS ?

Voilà, je sais que j'en demande beaucoup, mais ça fait je ne sais combien de temps (ça ce compte en mois...) que je ne parvient pas à finaliser ces programmes. Donc ça me déçois un peu de ne pas pouvoir réussir à finir ce projet :'-(

Voilà, en attendant votre réponse et en vous remerciant d'avance,

Brandon.

Portrait de Alex

Bonjour,

Je te conseille un module RTC pour avoir l'heure et la date en temps réel. C'est très utile (voir ma dernière vidéo sur l'enregistreur de données)

Ensuite, pour écrire dans l'EEPROM: https://www.arduino.cc/en/Tutorial/EEPROMWrite

Portrait de Brandon

Merci de ta réponse Alex. Ok pour le RTC, le problème est que lycée n'en a pas donc soit je vais devoir en commander un à mon propre compte, soit je vais devoir trouver une alternative, dont mon idée pour le shield GPRS :/

Pour la lien que tu m'as envoyé, je ne vois pas où stocker mes chiffres du numéro de téléphone: et comment les récupérer dans mon programme de l'envoi d'un SMS ?

Ma commande dans laquelle je dois mettre mon numéro est la suivante:

  Serial.println("AT+CMGS=\"+33XXXXXXXXX\"\r");

J'enregistre le numéro en entier sous forme de caractère ? (par exemple, quand je veux enregistrer j'ajoute de base "+33" et ne prend pas en compte le 0 en enregistrant tout le reste ?) Ou j'enregistre chiffre par chiffre en venant récupérer les chiffres directement dans les caractères ?