Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 3 of 3

Thread: Arduino scale & display for food dispenser & weight calculation

  1. #1
    Junior Member
    Join Date
    Sep 2020
    Posts
    8

    Arduino scale & display for food dispenser & weight calculation

    Hello,

    I have been looking at using a scale amplifier (similar to the HX-711) with an ESP32 & Teensy 3.2 (similar to most Arduinos) to weigh a food carrying dispenser before and after dispensing to find the weight dispensed by the container. I have connected a button to trigger the dispensing of the components where in essence it will turn a DC motor to turn an auger & dispense but that is not the main topic of this thread.

    My issue is with the calculation of the weight before the button is pressed. I am using the ESP32 as the Master which is measuring the weight from the amplifier and sending it to the Teensy 3.2 slave in accordance to the I2C protocol as found here:

    ESP32 code:

    Code:
    /**
       A simple sketch to test and demo the dispenser's current features
    */
    
    #include "Dispenser.h"
    #include <WiFi.h>
    #include <HTTPClient.h>
    #include <Wire.h>
    
    // Const
    const int dispensingTimout = 5000; //in milliseconds
    int prevWeight = 0;
    
    // Wifi constants
    const char* wifiSsid = "Crunchy";
    const char* wifiPassword = "muffin4me";
    const int httpConnectionTimeout = 500;
    const char* cartServiceURL = "http://10.0.0.88:8080/Cart";
    const char* pulseServiceURL = "http://10.0.0.88:8080/Pulse";
    
    static char weightstr[15];
    Dispenser dp;
    
    void setup()
    {
      Wire.begin();               
      Serial.begin(115200);
      // Initialise dispenser
    
      // Connect to WiFi
      WiFi.begin(wifiSsid, wifiPassword);
    
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.println("Connecting to WiFi...");
      }
    
      Serial.println("Connected to WiFi...");
      Serial.println(WiFi.localIP());
    
      dp.begin();
    }
    
    void loop()
    {
      if (WiFi.status() == WL_CONNECTED) {
        HTTPClient pulseClient;
        pulseClient.setConnectTimeout(httpConnectionTimeout);
        pulseClient.begin(pulseServiceURL);
        int pulseResponseCode = pulseClient.GET();
        pulseClient.end();
           
            
            // Keep filling container until timout is reached
            unsigned long startTime = millis();
            //while (millis() - startTime < dispensingTimout) {
              float weight = dp.getWeight();
              dtostrf(weight, 7, 2,weightstr);
              Serial.println(weightstr);
              Wire.beginTransmission(8); // transmit to device #8
              Wire.write(weightstr);
              Wire.endTransmission();    // stop transmitting
    
    
              String xml1 = "<CartItem xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://schemas.datacontract.org/2004/07/Dispenser.WebService.Model\">\r\n";
              String xml2a = "    <CardId>";
              String xml2b = "</CardId>\r\n";
              String xml3a = "    <MachineId>";
              String xml3b = "</MachineId>\r\n";
              String xml4a = "    <Weight>";
              String xml4b = "</Weight>\r\n";
              String xml5 = "</CartItem>";
    
              String payload = xml1 + xml2a + xml2b + xml3a + xml3b + xml4a + xml4b + xml5;
              //String payload = xml1 + xml2a + cardID + xml2b + xml3a + machineID + xml3b + xml4a + weightString + xml4b + xml5;
              Serial.println(payload);
    
              HTTPClient webclient;
              webclient.setConnectTimeout(httpConnectionTimeout);
              webclient.begin(cartServiceURL);
              webclient.addHeader("Content-Type", "application/xml");
              webclient.addHeader("Accept", "application/xml");
              int httpResponseCode = webclient.POST(payload);
    
              if (httpResponseCode == 200) {
                Serial.println("Sending data: success");
              } else {
                Serial.println("Sending data: failed");
              }
              webclient.end();
           }
    }
    Teensy 3.2 Code:

    Code:
    /**
       A simple sketch to test and demo the dispenser's current features
    */
    
    #include "DispenserData.h"
    #include "DispenserUI.h"
    #include "Dispenser.h"
    #include <Wire.h>
    
    // Const
    const int dispensingTimout = 5000; //in milliseconds
    float weight; 
    float prevWeight = 0;
    
    Dispenser dp;
    
    void setup()
    {
      dp.begin();
      // Show product screen at startup
      dp.clearScreen();
      dp.showProductScreen();
      Serial.begin(115200);
    }
    
    void loop()
    {
          // Continuosly check for rfid cards
          if (dp.isCardPresent()) {
            Serial.print("CardID: ");
            Serial.println(dp.getCardID());
            // If one is detected, toggle LED
            // and display sale screen
            dp.buzz();
            dp.clearScreen();
            dp.showSaleScreen(0);
            dp.ledOn();
    
            
            // Keep filling container until timout is reached
             unsigned long startTime = millis();
             while (millis() - startTime < dispensingTimout) {
                Wire.begin(8);                // join i2c bus with address #8
                Wire.onReceive(receiveEvent);
                 
              // Toggle motor depending on whether
              // button is pressed
              if (dp.isButtonPressed()) {
                startTime = millis();
                Serial.println("Dispensing.");
                dp.motorOn(255);
    //            Wire.onReceive(receiveEvent);
               } else {
                dp.motorOff();
              }
              delay(5000);
           }
    
            // After timout, "stop dispensing",
            // and return to product screen
            dp.motorOff();
            dp.ledOff();
            dp.clearScreen();
            dp.showProductScreen();
          }
          delay(2500);
    }
    void receiveEvent(int howmany) {
      
      String weightstring = "";
      while(Wire.available()) // loop through all but the last
      {
        char w = Wire.read(); // receive byte as a character
        weightstring = weightstring + w;
        //Serial.print(weightstring);         // print the character
      }
       weight = weightstring.toFloat(); // respond with message of 6 bytes // as expected by master
       dp.showSaleScreen(weight);
       prevWeight = weight; 
      
    }
    The idea is to take the weight measured before the button is pressed and store it in a float type variable. Then after the button dispensing timeout is done, the weight is measured yet again and subtracted from the initial weight before the button is pressed to give the weight dispensed. The issue comes in retrieving the weight value on the Teensy 3.2 before the while loop. I am not sure how to initialize the Wire.begin( 8 ) / Wire.onReceive(receiveEvent) to execute the code appropriately and have it return to the beginning. Any insight on how to perform this would be very welcome. I have also attached my classes with the slave and master code below for reference. Thank you!Firmware_master.zip firmware_slave.zip

  2. #2
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    23,077
    Look at File > Examples > Wire > slave_receiver for an example of using those functions.

    The wire library also has a master_writer example which you can run on the other side to send data to Teensy. I'd recommend running these 2 very simple examples first, so you know the I2C communication works. Best to get that tested with the simple example code before throwing in the complexity of so much other stuff.

  3. #3
    Junior Member
    Join Date
    Sep 2020
    Posts
    8
    Quote Originally Posted by PaulStoffregen View Post
    Look at File > Examples > Wire > slave_receiver for an example of using those functions.

    The wire library also has a master_writer example which you can run on the other side to send data to Teensy. I'd recommend running these 2 very simple examples first, so you know the I2C communication works. Best to get that tested with the simple example code before throwing in the complexity of so much other stuff.
    I have already tested the example code and was able to run a version of my project in it very well. As it stands, I am able to receive weight values from my master ESP32, my issue is that I can only appropriately do it when I plug Wire.begin() and Wire.onReceive() into the while loop in loop() as shown above. If I do not do this, my receiveEvent() function runs indefinitely and it prevents my Teensy 3.2 from returning back to the beginning of the loop to prompt for the RFID card.

    Also, the way I require my display to function is to consistently update the screen values with new weight difference received from the master ESP32 I2C while my dispenser button is pressed and then return the final value after the button is done being pressed; even when the ESP32 is not connected to the button but my Teensy 3.2 is.

    Component connections are as follows:

    ESP32 Master:
    - Load cell amplifier

    Teensy 3.2 Slave:
    -4.2 inch Waveshare e-paper display
    -LED embedded antivandal push button
    -MFRC522 RFID module
    -Piezo buzzer

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •