Aller au contenu

Messages recommandés

Posté(e)

Bonjour tout le monde,

un petit thread pour vous présenter un système dont certaines parties pourraient vous intéresser : un système d'impression piloté par la voix avec gestion du stock de bobines

Le système fait appel à plusieurs programme/circuit

Fonctionnement :

Une commande vocale du type "imprime le fichier en noir" va alors entrainer plusieurs actions :

  • une recherche du dernier fichier stl modifié sur le pc
  • la récupération des infos concernant l'impression en noir (température de la buse et du bed)
  • la génération du gcode par curaengine et l'obtention de la quantité de filament nécessaire
  • la récupération d'info concernant la bobine actuellement sur la balance : masse et couleur
  • -> Si la couleur et/ou la masse ne correspondent pas, le filament est retiré via l'envoi d'une commande M600
  • Lancement de l'impression via octoprint
  • Mise à jour de la quantité de filament dans la bobine jusqu'à la fin de l'impression

En dehors du côté fun à la Iron Man, la partie intéressante est la balance qui permet de connaitre en permanence la quantité de filament restant via un site internet

IMG_20190127_200834_01.thumb.jpg.2227b08bd04f1e525e46c1cdd608935f.jpgIMG_20190127_194623.thumb.jpg.14a71c55129617b54bcb9ed573cd3306.jpg

 

Vous pouvez voir sur ces 2 photos la balance ainsi que le lecteur RFID (le circuit l'électronique avec l'ESP se trouvant dans la boite à l'arrière) : le fonctionnement est simple : si le capteur de poids voit une différence importante (= on retire la bobine), il attends que le lecteur rfid scanne un code, ensuite il attend quelques secondes puis enregistre le poids de la bobine. Enfin, il envoie toutes les infos au serveur qui gère la suite (mise à jour des info de la bobine si celle si est enregistrée dans la BDD ou création d'une entrée dans le cas contraire)

 

1.thumb.png.a87263973f4acbcbad1581d5bfa88680.png

 

Capture d'écran du site de gestion : pour chaque bobine on peut rentrer la température d'impression (de la première couche et des suivantes, pour la buse et le bed) et on voit quelle quantité de filament il reste

Voici le code de l'ESP8266 (sous licence GNU GPL v3) (pour la partie web et la partie reconnaissance vocale/slicing ça ne sera pas possible dans l'immédiat, n'étant pas le seul à avoir travailler dessus) : (le code est largement optimisable mais si ça peut en aider certains tant mieux)

#include <SPI.h>
#include <MFRC522.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266HTTPUpdateServer.h>
#include <WiFiClientSecure.h>
#include <ArduinoJson.h>
#include <Adafruit_NeoPixel.h>

#include "HX711.h"

 
#define DOUT  4
#define CLK  5
 
HX711 scale(DOUT, CLK);
 
//Change this calibration factor as per your load cell once it is found you many need to vary it in thousands


#define zero_factor 190860

float oldPoids=0;

String myKey="";

String url = "/receive.php";
String host="https://host.fr";

String user="user";//website api
String token="token";//website api

unsigned long previousMillis ;


ESP8266HTTPUpdateServer httpUpdater; // instance pour l'OTA (obligatoire)


#define RST_PIN  0     // Configurable, see typical pin layout above
#define SS_PIN 15     // Configurable, see typical pin layout above

ESP8266WebServer server(7980);

const char *SERVER_WIFI_SSID = "XXXX";
const char *SERVER_WIFI_PASS = "XXXX";

String readRFID = "nok";
 
MFRC522 rfid(SS_PIN, RST_PIN); // Instance of the class

MFRC522::MIFARE_Key key; 

WiFiClientSecure client;



#define del 2
#define NUMPIXELS      1

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, del, NEO_GRB + NEO_KHZ800);



 
void setupWiFi()
{
  WiFi.mode(WIFI_STA);
   WiFi.begin(SERVER_WIFI_SSID,SERVER_WIFI_PASS);
  // WiFi.setAutoConnect(false);
 //  WiFi.setAutoReconnect(false);
   while(WiFi.status() != WL_CONNECTED)
   {
     delay(500);
     Serial.print("...");
   }
    Serial.println("connected");
      Serial.println(WiFi.localIP());   
}



void setup() { 
  Serial.begin(9600);
   pixels.begin();
    pixels.setPixelColor(0, 0,0,0);
  pixels.show();
  setupWiFi();
    httpUpdater.setup(&server); //on lance l'instance gérant l'OTA
  server.begin(); //on démarrage le serveur web

  
  SPI.begin(); // Init SPI bus
  rfid.PCD_Init(); // Init MFRC522 
  rfid.PCD_DumpVersionToSerial();  // Show details of PCD - MFRC522 Card Reader details
  scale.set_scale(-212760);  //Calibration Factor obtained from first sketch
  scale.set_offset(zero_factor);

  
  

  server.on("/", [](){ 
    if (server.argName(0)=="poids"){
      if (server.arg(0)=="now"){
        String poids=String(scale.get_units(5)*1000); //grammes
        Serial.println(poids);
        server.send(200, "text/html", poids);
      } else {
        if (server.arg(0)=="tare"){
          scale.tare();   
          Serial.println("Tare"); 
          server.send(200, "text/html", "tare");
        } else {
          if (server.arg(0)=="end") {
            String poids=String(scale.get_units(5)*1000); //grammes
            Serial.println(poids);
            sendIFM(myKey,poids,"end");
            server.send(200, "text/html", poids);
          }
        }
      }
    }
    if (server.argName(0)=="rfid"){
      if (server.arg(0)=="ok"){
        readRFID="ok";
        Serial.println(readRFID);
        server.send(200, "text/html", readRFID);
      } else {
        if (server.arg(0)=="last"){
          server.send(200, "text/html", myKey);
        }
      }
    }
    
  }); 

  readIFMRFID();
  oldPoids=scale.get_units(5)*1000;
  

  Serial.println("led");
  pixels.setPixelColor(0,255,255,255);
  pixels.show();
  delay(500);
  pixels.setPixelColor(0, 0,0,0);
  pixels.show();
  delay(500);
   pixels.setPixelColor(0,255,255,255);
  pixels.show();
  delay(500);
  pixels.setPixelColor(0, 0,0,0);
  pixels.show();

  previousMillis  = millis();
 
}




void readIFMRFID(){


  StaticJsonBuffer<200> jsonBuffer;
 
  
   
  String PostData = "{";
  PostData += "\"user\": \""+user+"\",";
  PostData += "\"token\": \""+token+"\",";
  PostData += "\"action\": \"esp_rfid\"}";

   
  Serial.println("connexion");
  
if (!client.connect(host, 443))
  {
   Serial.println("connection failed");
  return;
  } else {
    Serial.println("connecté");
  client.print(String("POST ") + url + " HTTP/1.1\r\n" +
                 "Host: " + host + "\r\n" +     
                 "Content-Type: application/json"+"\r\n" +
                 "Content-Length: " + PostData.length() + "\r\n" +
                 "\r\n" + // This is the extra CR+LF pair to signify the start of a body
                 PostData + "\n");

   while (client.connected()) {
    String line = client.readStringUntil('\n');
    if (line == "\r") {
      Serial.println("headers received");
      break;
    }
  }
  String line = client.readStringUntil('\n');
  
  JsonObject& root = jsonBuffer.parseObject(line);
  const char * tmp = root["rfid"];
  myKey = tmp;
  Serial.print("RFID Key : ");
  Serial.println(myKey);
  }
 
  
}






void sendIFM (String uid, String poids, String state){
  

  String PostData = "{";
  PostData += "\"user\": \""+user+"\",";
  PostData += "\"token\": \""+token+"\",";
  PostData += "\"rfid\": \""+uid+"\",";
  PostData += "\"action\": \"rfid\",";
  PostData += "\"state\": \""+state+"\",";
  PostData += "\"poids\": \""+poids+"\"}";

   
  
if (client.connect(host, 443))
  {
  client.print(String("POST ") + url + " HTTP/1.1\r\n" +
                 "Host: " + host + "\r\n" +     
                 "Content-Type: application/json"+"\r\n" +
                 "Content-Length: " + PostData.length() + "\r\n" +
                 "\r\n" + // This is the extra CR+LF pair to signify the start of a body
                 PostData + "\n");
  }

  
}




 
void loop() {

 server.handleClient();

 unsigned long currentMillis = millis();

 if (readRFID!="ok"){
  float newPoids=scale.get_units(5)*1000;
  Serial.print("new : ");
  Serial.println(String(newPoids));
  Serial.print("old : ");
  Serial.println(String(oldPoids));
  unsigned long currentMillis = millis();
  if (oldPoids-newPoids > 150 && (currentMillis - previousMillis >= 1000)){
    
    pixels.setPixelColor(0,0,0,255);
    pixels.show();
    delay(200);
    pixels.setPixelColor(0, 0,0,0);
    pixels.show();
    delay(200);
    pixels.setPixelColor(0, 0,0,255);
    pixels.show();
    delay(200);
    pixels.setPixelColor(0,0,0,0);
    pixels.show();

    
    previousMillis = currentMillis;
    readRFID="ok";  
  } else {
    Serial.println("old");
    oldPoids=newPoids;
    Serial.println("oldPoids");
    if (currentMillis - previousMillis >= 60000){
      sendIFM(myKey,String(newPoids),"end");  
      previousMillis = currentMillis;
      Serial.println("maj");
    }
    
  }
 }

 if (readRFID =="ok"){
  if ( rfid.PICC_IsNewCardPresent()){
    if (rfid.PICC_ReadCardSerial()){
      myKey=String(rfid.uid.uidByte[0],HEX)+ String(rfid.uid.uidByte[1],HEX) + String(rfid.uid.uidByte[2],HEX)  + 		String(rfid.uid.uidByte[3],HEX);
  
    pixels.setPixelColor(0,255,255,255);
    pixels.show();
    delay(200);
    pixels.setPixelColor(0,0,0,0);
    pixels.show();
    delay(200);
    pixels.setPixelColor(0, 255,255,255);
    pixels.show();
    delay(5000);

    String poids=String(scale.get_units(5)*1000); 
    pixels.setPixelColor(0,0,0,0);
    pixels.show();
    delay(200);
    pixels.setPixelColor(0, 0,0,255);
    pixels.show();
    delay(200);
    pixels.setPixelColor(0, 0,0,0);
    pixels.show();
    delay(200);
    pixels.setPixelColor(0, 0,0,255);
    pixels.show();
    delay(200);
    pixels.setPixelColor(0, 0,0,0);
    pixels.show();
   
    oldPoids=poids.toFloat();
    Serial.print("poids : ");
    Serial.println(String(poids));
    sendIFM(myKey,poids,"new");
    rfid.PICC_HaltA();
    rfid.PCD_StopCrypto1();
    readRFID="nok";
     
    }
  }  
 }
delay(200);
}

 

Bonne fin de week end.

Posté(e)
il y a 3 minutes, Janpolanton a dit :

Salut,

Intéressant, mais quand je vois ce que ça donne quand je dicte un sms, j'ai peur du résultat...

En fait la reconnaissance vocale de chromium marche plutot bien (alors que c'est sur un Rpi avec un simple micro USB), après y a un programme (serveur php) derrière qui filtre la réponse et s'assure d'avoir un bon taux de correspondance entre le texte traduit et la commande attendue. Mon système me permet de gèrer toute ma domotique et j'ai jamais eu de faux positifs pour le moment (et concernant ce système en particulier, il ne peut de toute façon rien se passer si l'imprimante est éteinte ou si elle imprime déjà ^^). Bon pour la reco vocale le gros problème c'est de passer par les serveurs de google :s  (mais le système se pilote aussi via une appli android ou un bete navigateur web)

Posté(e)

Je ne confierais pas la sécurité de mes biens et de mes proches à une appli de reconnaissance vocale.

Ce n'est que l'avis d'un vieux croûton de 66 ans...

Posté(e)
il y a 8 minutes, Janpolanton a dit :

Je ne confierais pas la sécurité de mes biens et de mes proches à une appli de reconnaissance vocale.

Ce n'est que l'avis d'un vieux croûton de 66 ans...

vu que je vis tout seul, ça va 😉 mais je suis d'accord.

Mais faut aussi voir qu'une bete appli android/navigateur web permet de commander le système aussi bien. La reco vocale n'est qu'un plus et j'espère un jour pouvoir me passer de google via le projet de Mozilla par exemple.

Concernant ce projet en particulier, actuellement j'utilise surtout la partie gestion des bobines qui est quand même franchement pratique (rien que pour savoir s'il me reste assez de PLA pour lancer l'impression)

Créer un compte ou se connecter pour commenter

Vous devez être membre afin de pouvoir déposer un commentaire

Créer un compte

Créez un compte sur notre communauté. C’est facile !

Créer un nouveau compte

Se connecter

Vous avez déjà un compte ? Connectez-vous ici.

Connectez-vous maintenant
  • Sur cette page :   0 membre est en ligne

    • Aucun utilisateur enregistré regarde cette page.
  • YouTube / Les Imprimantes 3D .fr

×
×
  • Créer...