sczrecycle

SmartCityZen Recycle

SCZ Recycle is a system to control their waste production. The purpose of the system is to increase the awareness of how our daily behavior has impact on the planet and the environment.

I installed it in my home and in just two days we realized that we have produced over 7.46 kg of rubbish!

We are living together in the family this since we quickly calculated that our impact on the city in one year is almost 1 ton of waste that someone will have to manage and dispose !!!
This perhaps allows us to see the infamous TAX ON WASTE like a proper contribution that my family must give the territory that hosts us.
What is needed?

FOR TRANSMITTER (Arduino)
1 HX711 is a breakout board that interfaces with the load cells of a scale, reads the data and transmits it to the Arduino.

HX711
It ‘a very inexpensive component (from 0.5 € to 2.5 €) here are some links:
Ebay 1
Ebay2 dalla Cina
Aliexpress

1 RF Receiver and 1 RF Transmitter 433MHz
Cost a few Euros
TX_RX_RF_arduino
Aliexpress

1 Arduino or compatible (I used a Luigino 1000Pads you see in the picture)
luigino
Aliexpress Arduino UNO

1 kitchen scale than those with a max. of 5.7 Kg weight.
(Normally in a waste basket “under the sink” There are 1.5 to 3 kg of waste)
scale_hacking
Aliexpress

A bit of cables and possibly a breadboard or a matrix board.

FOR THE RECEIVER

1 Arduino or compatible (I used a Luigino1000Pads you see in the image.

luigino
Aliexpress Arduino UNO
Aliexpress Arduino Pro Micro

n.1 LCD Display 1602
character_2x16_modules_lcd_display_hd44780_controller_black_on_yg
Aliexpress

STEP 1 – Transmitter System

Take off the scale (it is held together by a few screws), inside you’ll find something like this:
celladicarico

It is the load cell.
Works: 4 wires are connected to it that are the 4 points of a Wheatstone bridge I am not to deepen technically (if you are interested in the following page) into practice by applying a voltage of 2 of these wires you can read a voltage change on other 2 as a function of the pressure at which the load cell is subjected.
in practice it is greater the greater weight is the change in voltage.

These 4  wires are connected to an electronic base inside the balance and connect to 4 points named as follows:

E + : Excitation voltage +
E- : Excitation voltage –
S + : Signal +
S- : Signal –

And Just connect these four wires to our at HX711 respective pin

 

namely: E + with E +, E- with E-, S+ with A+, S- with A-.

At this point we have to connect the HX711 and the RF transmitter from 433Mhz with Arduino, this the wiring diagram:

First you need to install a library in Arduino, named:

HX711 Library

STEP 2 – Calibration Scales

There is a small code  help that I have  changed from the examples of the library, there is a sketch for calibration but for me it was easier to proceed with trial with this sketch, then install the library and upload the sketch:

/*
 Questo sketch consente la calibrazione di una bilancia con HX711
 
 This example code uses bogde's excellent library: https://github.com/bogde/HX711
 bogde's library is released under a GNU GENERAL PUBLIC LICENSE
 
 The HX711 does one thing well: read load cells. The breakout board is compatible with any wheat-stone bridge
 based load cell which should allow a user to measure everything from a few grams to tens of tons.

 Arduino pin A0 -> HX711 SCLK
 Arduino pin A1 -> HX711 DAT o DOUT
 Arduino 5V -> HX711 VCC
 Arduino GND -> HX711 GND
 
 la scheda può essere alimentata da 2.7V a 5.0V
 
*/

#include "HX711.h"

#define valoredicalibrazione -7050.0 //Questo è il valore da modificare fino a raggiungere la corretta misura può essere negativo o positivo


HX711 scale(A1, A0); //il parametro "gain" HX711(Dout,Sck,gain) se omesso assume il valore di default di 128

void setup() {
  Serial.begin(9600);
  Serial.println("HX711 scale demo");

  scale.set_scale(valoredicalibrazione); //Seleziona il parametro di calibrazione
  scale.tare();    //Azzera la tara 

  Serial.println("Letture:");
}

void loop() {
  Serial.print("Lettura: ");
  Serial.print(scale.get_units(), 2); //scale.get_units() returns a float
  Serial.print(" Kg"); //You can change this to kg but you'll need to refactor the calibration_factor
  Serial.println();
}

Opening the Arduino Serial Monitor will see that begin to read in sequence the value of the balance, no object will mark the weight of 0.0 Kg.
Now take an object (a glass, an apple what you will) weigh it with a kitchen scale and then place it on the connected scale in Arduino.
By changing constant: valoredicalibrazione at line 22 you will see that the weight shown in the Serial Monitor will change, make several attempts until you find the value that gives the correct weight of the object (may be expressed in grams and not Kg).
When the value is equal to the reading on the kitchen scale made before the system is calibrated !!!
Now you can try any other object confirming the correct reading.

STEP 3 – We load SCORE TX (transmitter)
And here is the sketch SCZRE TX to upload to Arduino …

#include "HX711.h"
#include <JeeLib.h>
#include <Manchester.h>
ISR(WDT_vect) {Sleepy::watchdogEvent();}

// HX711.DOUT    - pin #A1
// HX711.PD_SCK	- pin #A0
/*
 * How to Calibrate Your Scale

1. Call set_scale() with no parameter.
2. Call tare() with no parameter.
3. Place a known weight on the scale and call get_units(10).
4. Divide the result in step 3 to your known weight. You should get about the parameter you need to pass to set_scale.
5. Adjust the parameter in step 4 until you get an accurate reading.
 */
// HX711 (Dout,Sck)
HX711 scale(A1, A0);		// parameter "gain" is ommited; the default value 128 is used by the library

#define TX_PIN 6  //pin where your transmitter is connected
#define BUFFER_SIZE 50
#define LED_PIN 13
#define CELL_PIN A0


//*********** SERIAL NUMBER ***********
char SerialSens[ ]="SCZRE0364";
//*************************************

int volt=0;
char messaggio[32];
unsigned char data[BUFFER_SIZE]="";
char msg[BUFFER_SIZE];
char msg2[10];
char msg3[10];
char msg4[10];
float carica=0;
char vuota[32]="";
int offset_scale=53;

// How often do we do readings?
long time = 0; //
int timeBetweenReadings = 500; // We want a reading every 200 ms;


void setup() {
  Serial.begin(9600);
  man.workAround1MhzTinyCore(); //add this in order for transmitter to work with 1Mhz Attiny85/84
  man.setupTransmit(TX_PIN, MAN_600);
  
  pinMode ( LED_PIN, OUTPUT);
  pinMode ( TX_PIN, OUTPUT);

  
  Serial.println("HX711 Demo");

  Serial.println("Before setting up the scale:");
  Serial.print("read: \t\t");
  Serial.println(scale.read());			// print a raw reading from the ADC

  Serial.print("read average: \t\t");
  Serial.println(scale.read_average(20));  	// print the average of 20 readings from the ADC

  Serial.print("get value: \t\t");
  Serial.println(scale.get_value(5));		// print the average of 5 readings from the ADC minus the tare weight (not set yet)

  Serial.print("get units: \t\t");
  Serial.println(scale.get_units(5), 1);	// print the average of 5 readings from the ADC minus tare weight (not set) divided 
						// by the SCALE parameter (not set yet)  

  scale.set_scale(291.00);                      // this value is obtained by calibrating the scale with known weights; see the README for details
  scale.tare();				        // reset the scale to 0

  Serial.println("After setting up the scale:");

  Serial.print("read: \t\t");
  Serial.println(scale.read());                 // print a raw reading from the ADC

  Serial.print("read average: \t\t");
  Serial.println(scale.read_average(20));       // print the average of 20 readings from the ADC

  Serial.print("get value: \t\t");
  Serial.println(scale.get_value(5));		// print the average of 5 readings from the ADC minus the tare weight, set with tare()

  Serial.print("get units: \t\t");
  Serial.println(scale.get_units(5), 1);        // print the average of 5 readings from the ADC minus tare weight, divided 
						// by the SCALE parameter set with set_scale

  Serial.println("Readings:");
}

void loop() {
  
  Serial.print("\t| PESO:\t");
  float peso=-scale.get_units(10);
  if (peso>-3 && peso<3) peso=0;
  Serial.print(peso, 0);Serial.println(" gr.");
  delay(50);
  
 
  
  dtostrf(peso, 4, 1,msg2);
  
   
   float risultato=readVcc();
    
    dtostrf(risultato, 4, 0,msg4);
    carica=risultato/1000;
    dtostrf(carica, 1, 3,msg4);

    strcpy(msg,"");    
    strcat(msg, "SN:");
    strcat(msg, SerialSens);
    strcat(msg, "PE:");
    strcat(msg, msg2); 
    strcat(msg, "BT:");
    strcat(msg, msg4);   
    
    
    
    
      for (int i=0;i<=BUFFER_SIZE;i++)
    {
      data[i]=msg[i];    
    }
    digitalWrite(LED_PIN, true); //Lampeggia il led al ricevimento del messaggio
    delay(10);
    digitalWrite(LED_PIN, false);
    man.transmitArray(BUFFER_SIZE,data);
    
    
    
     scale.power_down();              // put the ADC in sleep mode
  Sleepy::loseSomeTime(30000);
  scale.power_up();
}

float readVcc() {
  // Read 1.1V reference against AVcc
  // set the reference to Vcc and the measurement to the internal 1.1V reference
  #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
    ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  #elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
    ADMUX = _BV(MUX5) | _BV(MUX0);
  #elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
    ADMUX = _BV(MUX3) | _BV(MUX2);
  #else
    ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  #endif  
 
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Start conversion
  while (bit_is_set(ADCSRA,ADSC)); // measuring
 
  uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH  
  uint8_t high = ADCH; // unlocks both
 
  long result = (high<<8) | low;
 
  result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
  return result; // Vcc in millivolts
}

Obviously at line 71 change the value with what you got during calibration.
The sketch is based on the transmission protocol used by the SmartCityZen project, and then compared to the single waste control functionality there are some redundant information sent (for example the sensor code or battery volt).
In this way, however, the transmitted data can be read from SCZ Station and transferred via the Internet on SmartCityZen Web Web server and shared through the portal.
The sketch sends to the receiver every 30 seconds the weight of waste, this value can be changed sempolicemente changing the value of this command
Sleepy :: loseSomeTime (30000);
Modifying 30000 mS up to a max value of 60000 mS,
which provides a pause of 1 minute, to increase it and make for example un’invio every 3 minutes using the following syntax:
Sleepy :: loseSomeTime (60000);
Sleepy :: loseSomeTime (60000);
Sleepy :: loseSomeTime (60000);
Recalling 3 times the command.

STEP 4 – Receiver System
The receiver system requires the Arduino connection with the display 1602 and the RF receiver to 433 MHz.

According to this wiring diagram:

Fritzing Scheme SCZRE RX_bb

And this is the sketch to load:

/* -------------------------------------------------------------------------------

// Monitoraggio produzione rifiuti casalinghi con SCZRE
con display LCD 16x2 1602
con registrazione in EPROM del totrifiuti
e dell'ulima pesata

// www.smartcityzen.it
 */
#include <LiquidCrystal.h>
#include <SPI.h>
#include <SD.h>
#include <Manchester.h>
#include <string.h>
#include <EEPROMex.h>


// Connections:
// rs (LCD pin 4) to Arduino pin 12
// rw (LCD pin 5) to Arduino pin 11
// enable (LCD pin 6) to Arduino pin 10
// LCD pin 15 to Arduino pin 13
// LCD pins d4, d5, d6, d7 to Arduino pins 5, 4, 3, 2

// Ricevitore RF connesso a pin 7 arduino

LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);

int backLight = 13;    // pin 13 will control the backlight

//Configurazione Libreria Manchester per trasmissione
#define RX_PIN 7
#define BUFFER_SIZE 50
uint8_t buffer[BUFFER_SIZE];
unsigned char message[BUFFER_SIZE];

#define LED_PIN 13
char SensMessage[] = "SCZXX";

// Memorizzazione totale rifiuti
String dataInizio = "02/01/2016";
int addressFloat = 0;
int addressFloatPeso=5;
boolean scarico=HIGH;
float totRifiuti = 0.0;


float precPeso = 0;
float nowPeso = 0;


void setup()
{
  Serial.begin(9600);
  //EEPROM.writeFloat(addressFloat,totRifiuti);
  //EEPROM.writeFloat(addressFloatPeso,precPeso);
  pinMode(backLight, OUTPUT);
  digitalWrite(backLight, LOW); // turn backlight on. Replace 'HIGH' with 'LOW' to turn it off.
  lcd.begin(16, 2);             // columns, rows.  use 16,2 for a 16x2 LCD, etc.
  lcd.clear();                  // start with a blank screen
  lcd.setCursor(0, 0);          // set cursor to column 0, row 0 (the first row)
  lcd.print("SCZ Recycle");    // change this text to whatever you like. keep it clean.
  lcd.setCursor(0, 1);          // set cursor to column 0, row 1
  lcd.print("smartcityzen.it");
  totRifiuti = EEPROM.readFloat(0);
  precPeso=EEPROM.readFloat(5);


  //Configurazione Manchester
  man.setupReceive(RX_PIN, MAN_600);
  man.beginReceiveArray(BUFFER_SIZE, buffer);

  delay(500);
  lcd.clear();                  // start with a blank screen
  lcd.setCursor(0, 0);          // set cursor to column 0, row 0 (the first row)
  lcd.print("Attendi");
}

void loop()
{

  if (man.receiveComplete())
  {
    uint8_t receivedSize = 0;
    Serial.println("Ricevuto: ");
    digitalWrite(LED_PIN, HIGH);
    delay(100);
    digitalWrite(LED_PIN, LOW);
    for (int i = 0; i < BUFFER_SIZE; i++)
    {

      message[i] = char(buffer[i]);
      Serial.print(char(message[i]));
    }
    Serial.println();
    Serial.print("SENSORE: ");
    for (int t = 0; t < 5; t++)
    {
      SensMessage[t] = message[t + 3];
    }
    String messstr = String(SensMessage);
    Serial.println(messstr);




    if (messstr == "SCZRE")
    {
      Serial.println("Ricevuto un SCZ RECYCLING");
      gestioneSCZRE();
    }
    man.beginReceiveArray(BUFFER_SIZE, buffer);

  }
  else
  {
    
    lcd.setCursor(0, 0);
    lcd.print("TOT: ");
    lcd.print(totRifiuti+nowPeso);
    lcd.print(" KG");
    Serial.print("totRifiuti:");Serial.println(totRifiuti);
    lcd.setCursor(0, 1);
    lcd.print("NOW: ");
    lcd.print(nowPeso);
    lcd.print(" KG");
    Serial.print("nowPeso:");Serial.println(nowPeso);
  }
}

//---------------------------------SCZRE--------------------------
void gestioneSCZRE()
{







  Serial.print("IN FUNZIONE: ");
  for (int i = 0; i < BUFFER_SIZE; i++)
  {


    Serial.print(char(message[i]));
  }

  String nowRifiuti = "";
  Serial.print("nowRifiuti:");Serial.println(nowRifiuti);
  for (int i = 0; i < 5; i++)
  {
  nowRifiuti = nowRifiuti + char(message[i + 15]);
  Serial.print(char(message[i + 15]));
  }
  Serial.print("nowRifiuti:");Serial.println(nowRifiuti);
  nowPeso = nowRifiuti.toFloat();
  if (precPeso==0)
  {
    precPeso=nowPeso;
  }
  if (nowPeso<0.1 && scarico==LOW)
  {
    totRifiuti=totRifiuti+precPeso;
    EEPROM.writeFloat(addressFloat,totRifiuti);
    EEPROM.writeFloat(addressFloatPeso,precPeso);
    scarico=HIGH;
  }
  if (nowPeso>1)
  {
    scarico=LOW;
  }
  Serial.print("nowPeso:");Serial.println(nowPeso);






}

 

CONCLUSION
And here are the pictures of the final project.

Actually because I wanted to use the TX system with a battery I replaced the Arduino ATMEGA328 with breadboard, reducing size and consumption.

One thought on “SmartCityZen Recycle”

  1. I wanted to thank you for this excellent read!!

    I definitely enjoyed every little bit of it. I’ve got you saved as a favorite to
    check out new things you post…

Leave a Reply

Your email address will not be published. Required fields are marked *