const int PinButton2=2;//Action
const int PinButton3=3;//Roll option high priority button (on loop)
const int PinButton4=4;//digit [0-9] edit (slow) , position of digit in number roll
//const int PinButton5=5;//no need,,,primitive load program!
const int PinHx711DT=6;
const int PinHx711SCK=7;
const int PinDht=8;
//i2C lcd 16x2
//const int PinLcdScl;//my arduino has those pins....Scl and Sda for I2C
//const int PinLcdSda;
///////////////////////////////////
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);
////////////////////////////////////
#include "DHT.h"
#define DHTPIN PinDht
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
void lcdPrintTempHum(){
lcd.setCursor(0,1);
String str=F("");
float t = dht.readTemperature();
float h = dht.readHumidity();
if(isnan(t) || isnan(h)){
str+=F("Error Temp | Hum");
}
else{str+=t;str+=F(" C ");str+=h;str+=F("%");}
lcd.print(str);
}
///////////////////////////////////////////////////////
#include "HX711.h"
HX711 scale;
//EEPROM ONE BYTE
byte LoadsUsing=0;// NON - CALLIBRATED ...just showing the HX711 readings
//EEPROM 10*4 =40 bytes
long LoadsSamplesAverage[10];//////{115315,181679,318885,525671,1002444};
//EEPROM 10*4 =40 bytes
long LoadsStandarts[10]; ///// { 0, 295, 885, 1775, 3776};
//total eeprom 81 bytes
////////////////////////////////////////////////////////////////////////////
#include <EEPROM.h>
#include <avr/pgmspace.h>
void updateEEPROM(){
updateEEPROMforHX711Datautils();
}
void updateLongsToEEPROM(int address,long * SourceArray,int SourceLength){
int i=0;
long l;
while(i<SourceLength){
l=SourceArray[i];
long b0=l;b0>>=24;
long b1=l;b1>>=16;
long b2=l;b2>>=8;
long b3=l;
EEPROM.update(address, (byte)b0);++address;
EEPROM.update(address, (byte)b1);++address;
EEPROM.update(address, (byte)b2);++address;
EEPROM.update(address, (byte)b3);++address;
++i;
}
}
void readLongsFromEEPROM(int address,long * TargetArray,int TargetLength){
int i=0;
long l;
while(i<TargetLength){
byte b0=EEPROM.read(address);++address;
byte b1=EEPROM.read(address);++address;
byte b2=EEPROM.read(address);++address;
byte b3=EEPROM.read(address);++address;
l=b0;l<<=8;
l+=b1;l<<=8;
l+=b2;l<<=8;
l+=b3;
TargetArray[i]=l;
++i;
}
}
void readEEPROM(){
int addr=0;
byte firstByteBetterBePass=EEPROM.read(addr);
if(firstByteBetterBePass>=2 && firstByteBetterBePass<=10){
LoadsUsing=firstByteBetterBePass;
//onl("Just Read from EEPROM that i have callibrate this loadcell-chip for standart weights : ",LoadsUsing);
}
else{
//ons("Seems that EEProm is not on the proper format !!!");
return;
}
++addr;
readLongsFromEEPROM(addr,LoadsStandarts,LoadsUsing);
addr+=40;
readLongsFromEEPROM(addr,LoadsSamplesAverage,LoadsUsing);
addr+=40;
Serial.println(LoadsUsing);
int i=0;
while(i<LoadsUsing){
Serial.print(LoadsStandarts[i]);
Serial.print(F("->"));
Serial.println(LoadsSamplesAverage[i]);
++i;
}
Serial.println();
}
void updateEEPROMforHX711Datautils(){
Serial.println("Updating eep+ROM");
EEPROM.update(0,LoadsUsing);
updateLongsToEEPROM(1,LoadsStandarts,10);
updateLongsToEEPROM(41,LoadsSamplesAverage,10);
}
//void flushToZeroEEPROM(){int i=0;while(i<100){EEPROM.update(i,0);++i;}}
/*
void initAndFlushToEEPROMMyStandarts(){//from my 10 kg beam load cell
LoadsUsing=5;
LoadsStandarts[0]=0;LoadsSamplesAverage[0]=115315; // 0 grams hx711 reads 115315
LoadsStandarts[1]=295;LoadsSamplesAverage[1]=181679; //295 grams hx711 reads 181679
LoadsStandarts[2]=885;LoadsSamplesAverage[2]=318885;
LoadsStandarts[3]=1775;LoadsSamplesAverage[3]=525671;
LoadsStandarts[4]=3776;LoadsSamplesAverage[4]=1002444;
LoadsStandarts[5]=0;LoadsSamplesAverage[5]=0; ////unused
LoadsStandarts[6]=0;LoadsSamplesAverage[6]=0;
LoadsStandarts[7]=0;LoadsSamplesAverage[7]=0;
LoadsStandarts[8]=0;LoadsSamplesAverage[8]=0;
LoadsStandarts[9]=0;LoadsSamplesAverage[9]=0;
updateEEPROMforHX711Datautils();
Serial.println(F("EEPROM being flushed from 81 bytes !"));
}
*/
void setup(){
pinMode(PinButton2,INPUT_PULLUP);
pinMode(PinButton3,INPUT_PULLUP);
pinMode(PinButton4,INPUT_PULLUP);
Serial.begin(9600);
dht.begin();
lcd.begin();
scale.begin(PinHx711DT,PinHx711SCK);
delay(323);
//flushToZeroEEPROM();
//initAndFlushToEEPROMMyStandarts();
//ons("reading eeprom");
readEEPROM();
//ons("eeprom done reading");
setupZygaria();
}
byte but2Curr=0;
byte but2Prev=0;
void but2Read(){but2Curr=digitalRead(PinButton2);}
bool but2Changed(){return but2Curr!=but2Prev;}
bool but2JustPressed(){return but2Curr<but2Prev;}
bool but2JustReleased(){return but2Curr>but2Prev;}
long last2Pressed;
byte but3Curr=0;
byte but3Prev=0;
void but3Read(){but3Curr=digitalRead(PinButton3);}
bool but3Changed(){return but3Curr!=but3Prev;}
bool but3JustPressed(){return but3Curr<but3Prev;}
bool but3JustReleased(){return but3Curr>but3Prev;}
byte but4Curr=0;
byte but4Prev=0;
void but4Read(){but4Curr=digitalRead(PinButton4);}
bool but4Changed(){return but4Curr!=but4Prev;}
bool but4JustPressed(){return but4Curr<but4Prev;}
bool but4JustReleased(){return but4Curr>but4Prev;}
long last4Pressed;
void readButtons(){but2Read();but3Read();but4Read();}
void storeButtons(){but2Prev=but2Curr;but3Prev=but3Curr;but4Prev=but4Curr;}
int delaying=123;
void loop(){
loopZygaria();
}
long gramsDifTemp=0;
void setGramsDif(long newGramsDif){
gramsDifTemp=newGramsDif;
Serial.print("Grams Offset setted to: ");
Serial.println(gramsDifTemp);
}
bool errorHX711sensor=false;
long lastReading;
bool readWeightFromHx711(){
//ons("reading");
//if return true means is Ready...
//if false not ready and timout and maybe broken pin connection etc ..or general problem with xh711
if(scale.wait_ready_timeout(3000)){
errorHX711sensor=false;//ons("ok");
lastReading=scale.read();//now 'safelly' attempt to read..
return true;
}
else{
errorHX711sensor=true;//ons("error cant read from sensor");
return false;
}
}
void zygariaResetZeroGrams(){
if(readWeightFromHx711()){
setGramsDif(loadTranslateNewReading(lastReading));
}
}
///showing only multipliers
int multiplier[]={1,10,100,1000};
int multiplierLength=4;
int multiplierCurr=0;
//grams is the relative from callibration output.
double units;//units= grams / multiplier[multiplierCurr];
String strWeight("");
void lcdPrintWeight(){
strWeight=F("");
if(readWeightFromHx711()){
long grams=loadTranslateNewReading(lastReading);
grams-=gramsDifTemp;
units=grams;
units/=multiplier[multiplierCurr];
strWeight+=units;
strWeight+=F("(");
strWeight+=lastReading;
strWeight+=F(")");
}
else{
strWeight+=F("ErrorHX711sensor");
}
lcd.print(strWeight);
}
long loadTranslateNewReading(long newReading){
float lastGrams=lastReading;
//ser.print(F("Checking last Reading = "));ser.println(lastReading);
if(LoadsUsing<2){
//ser.println(F("Not callibrated return 0,leaving new users to callibrate and understand hx711"));
}
else{
byte i=LoadsUsing-1;
long av=LoadsSamplesAverage[i];
long avpreOrForZero;
//ser.print(F("last average "));ser.println(av);
if(lastReading<av){
i=1;
while(i<LoadsUsing){
av=LoadsSamplesAverage[i];
//ser.println(i);ser.print(F("average "));ser.println(av);
if(av<lastReading){++i;}
else{//ser.print(F("breaking "));ser.println(i);
break;}
}
if(i>1){
avpreOrForZero=LoadsSamplesAverage[i-1];
if(lastReading-avpreOrForZero<av-lastReading){
av=avpreOrForZero;
i--;
//ser.print(F("Much closer to previus"));
}
//ser.println(i);
}
//else{ser.println(F("Using first"));}
}
//else{ser.println(F("Using last"));}
//ser.print(i);ser.print(F(" FINAL av "));ser.println(av);
avpreOrForZero=LoadsSamplesAverage[0];
lastGrams-=avpreOrForZero;
lastGrams*=LoadsStandarts[i];//NOT IN PREVIUS LINE to NOT OVERFLOW...
lastGrams/=(av-avpreOrForZero);
}
return lastGrams;
/*
if(LoadsUsing<1){
//ons("Not callibrated return 0,leaving new users to callibrate and understand hx711");
return 0;
}
int i=0;
while(i<LoadsUsing){if(newReading>LoadsSamplesAverage[i]){break;}++i;}
if(i<2){i=1;}
else if(i<LoadsUsing){
long difLeft=newReading-LoadsSamplesAverage[i-1];
long difRight=LoadsSamplesAverage[i]-newReading;
if(difLeft<=difRight){--i;}
else{}
}
else{i=LoadsUsing-1;}
return ((newReading-LoadsSamplesAverage[0])*(LoadsStandarts[i]))/(LoadsSamplesAverage[i]-LoadsSamplesAverage[0]);
*/
}
void lcdPrintWeightTempHum(){
lcd.clear();
lcdPrintWeight();
lcdPrintTempHum();
}
double sum=0;
double sum2=0;
double aver;
long reads;
long maxi=-2147483647;
long mini=2147483646;
int prii=0;
int priSamples;
void lcdPrintAverageProgress(){
lcd.clear();lcd.print(prii);lcd.print(F("/"));lcd.print(priSamples);lcd.print(F(" "));lcd.print(sum2);
lcd.setCursor(0,1);lcd.print(mini); lcd.print(F("-"));lcd.print(maxi);
}
void computeAverage(int Samples){
if(Samples<1){Samples=1;}
priSamples=Samples;
computeAverage();
}
void computeAverage(){
prii=0;
sum=0;
maxi=-2147483647;
mini=2147483646;
sum2=scale.read();
lcdPrintAverageProgress();
while(prii<priSamples){
reads=scale.read();
sum+=reads;
sum2+=reads;sum2/=2.0;
if(reads<mini){mini=reads;}
if(reads>maxi){maxi=reads;}
++prii;
if(prii%23==0){
lcdPrintAverageProgress();
}
}
aver=sum/priSamples;//now use average instead of sum2!
lcdPrintAverageProgress();
//onl("minmax (",mini," , ",maxi,") dif = ",(maxi-mini));
//ond("sum : ",sum, " / ",priSamples," = ",aver);
//ond("sum2 : ",sum2);//i thought double will overflow!....anyway..
}
byte setupReadings=5;
bool takeZeroMeasurements=true;
void setupZygaria(){
//ons("Activating Zygaria");
lcd.print(F("welcome"));
delay(456);
lcdPrintWeightTempHum();
if((!errorHX711sensor) && takeZeroMeasurements){//ons("zeroing");
computeAverage(setupReadings);
setGramsDif(loadTranslateNewReading(aver));
}
lcdPrintWeightTempHum();
//set lastPressed to not take some action on begining
last2Pressed=millis();
//ons("done setup");
}
int optionCurr=0;
String options[]={String("1.Sensoring"),String("2.Units"),String("3.Callibration"),String("4.See Standarts")};
int optionsLength=4;
void loopZygaria(){
readButtons();
if(but3JustPressed()){
rollOption();
}
else{
delaying=123;
runOption();
}
storeButtons();
//oni("delaying : ",delaying);
delay(delaying);
}
void rollOption(){
optionCurr++;
optionCurr%=optionsLength;
resetOption();
}
void resetOption(){
lcd.clear();
lcd.print(options[optionCurr]);
//oni("New Option ",optionCurr);
delay(123);
if(optionCurr==0){
selectSensoring();
}
else if(optionCurr==1){
selectUnits();
}
else if(optionCurr==2){
selectCallibrating();
}
else if(optionCurr==3){
selectShowCallibratedValues();
}
}
void runOption(){
if(optionCurr==0){
runSensoring();
}
else if(optionCurr==1){
runUnits();
}
else if(optionCurr==2){
runCallibrating();
}
else if(optionCurr==3){
runShowCallibratedValues();
}
}
long resetZygariaOver=1000;
void selectSensoring(){
lcdPrintWeightTempHum();
}
void runSensoring(){//ons("sensing");
if(but2JustPressed()){
lcdPrintWeightTempHum();
last2Pressed=millis();
//onS(strWeight);
}
else if(but2JustReleased()){
if(millis()-last2Pressed>resetZygariaOver){
if(!errorHX711sensor){
//ons("reseting to zero grams");
zygariaResetZeroGrams();
lcdPrintWeightTempHum();
}
}
}
}
void selectUnits(){
lcd.setCursor(0,1);
lcd.print(F("Mult: "));
lcd.print(multiplier[multiplierCurr]);
}
void runUnits(){
if(but2JustPressed()){
++multiplierCurr;
multiplierCurr%=multiplierLength;
lcd.clear();
lcd.print(F("Mult: "));
lcd.print(multiplier[multiplierCurr]);
lcd.setCursor(0,1);
lcdPrintWeight();
}
}
int currShowing=0;
void selectShowCallibratedValues(){
delay(1000);
currShowing=0;
lcd.clear();
lcd.print(LoadsUsing);
lcd.print(F(" StandartsUsing"));
lcd.setCursor(0,1);
lcd.print(F("HX711 to-> grams"));
}
void runShowCallibratedValues(){
if(but2JustPressed()){
if(LoadsUsing > 0){//or >1 !!...
lcd.clear();
lcd.print(currShowing);
lcd.print(F(")"));
lcd.print(LoadsSamplesAverage[currShowing]);
lcd.setCursor(0,1);
lcd.print(F("->"));
lcd.print(LoadsStandarts[currShowing]);
lcd.print(F(" grams"));
++currShowing;
currShowing%=LoadsUsing;
}
}
}
//editing variables for callibration
long tempAverages[10];
long tempStandarts[10];
byte tempRequestedStandarts=4;//except zero ,proposing 4 (0%,25%,50%,75%,99%)
byte tempRequestedStandartEditing=1;
int tempSampling=100;
byte tempGrams[6];//max = 999kg and 999 grams
byte tempGramsDigitEditing=5;
void resetTempGramsFromStandartEditing(){
int val=tempStandarts[tempRequestedStandartEditing];
int i=5;
int ypoloipo;
while(i>=0){
ypoloipo=val%10;
tempGrams[i]=ypoloipo;
val/=10;
--i;
}
}
//0.unstarted,,,must reset in case to cancell what ever edit until now
//1.enter number of standart weights[1,9]
//2.select number of samples 100,500,1000 (from HX711 sensor) per standart weight
//3.empty and press to average zero
//4.for(each standarts)
///////put the standart in scale , enter weight ,press and wait to take the average
int callibrStep=0;
void selectCallibrating(){
if(errorHX711sensor){
lcd.print(F("Callibration cant run"));
lcd.setCursor(0,1);
lcd.print(F("if sensor not working"));
delay(2345);
rollOption();//??!!!
return;////!!!????
}
//callibrStep=0;//?????cancel?
if(callibrStep==0){
lcd.setCursor(0,1);
lcd.print(F("press to start"));
}
else if(callibrStep==1){
lcd.clear();
lcd.print(F("#Standarts[1,9]"));
lcd.setCursor(0,1);
lcd.print(tempRequestedStandarts);
lcd.setCursor(0,1);
lcd.blink();
}
else if(callibrStep==2){
lcd.clear();
lcd.print(F("Select sampling"));
lcd.setCursor(0,1);
lcd.print(tempSampling);
}
else if(callibrStep==3){
lcd.clear();
lcd.print(F("RemoveAllWeights"));
lcd.setCursor(0,1);
lcd.print(F("Press And Wait"));
}
else if(callibrStep==4){
lcd.clear();
lcd.print(F("Put Standart#"));
lcd.print(tempRequestedStandartEditing);
lcd.setCursor(0,1);
lcd.print(F("grams="));
int i=0;while(i<6){lcd.print(tempGrams[i]);++i;}
lcd.setCursor(6+tempGramsDigitEditing,1);
lcd.blink();
}
}
void runCallibrating(){
if(callibrStep==0){run0CallibratingStep();}
else if(callibrStep==1){run1CallibratingStep();}
else if(callibrStep==2){run2CallibratingStep();}
else if(callibrStep==3){run3CallibratingStep();}
else if(callibrStep==4){run4CallibratingStep();}
}
void run0CallibratingStep(){
if(but2JustPressed()){
tempRequestedStandarts=4;//proposing zero+4 more for accuracy
tempRequestedStandartEditing=1;//will start from this after taking average of zero(empty)
tempGramsDigitEditing=5;
int i=0;
while(i<10){tempAverages[i]=0;tempStandarts[i]=0;++i;}
resetTempGramsFromStandartEditing();
callibrStep=1;
selectCallibrating();
}
}
void run1CallibratingStep(){
if(but4JustPressed()){
++tempRequestedStandarts;
if(tempRequestedStandarts>9){
tempRequestedStandarts=1;
}
selectCallibrating();
}
else if(but2JustPressed()){
//oni("Requested to edit standart weights: ",tempRequestedStandarts);
callibrStep=2;
selectCallibrating();
}
}
void run2CallibratingStep(){
if(but4JustPressed()){
if(tempSampling==100){tempSampling=500;}
else if(tempSampling==500){tempSampling=1000;}
else {tempSampling=100;}
selectCallibrating();
}
else if(but2JustPressed()){
callibrStep=3;
selectCallibrating();
}
}
void run3CallibratingStep(){
if(but2JustPressed()){//compute avrage on empty load
computeAverage(tempSampling);
tempRequestedStandartEditing=0;
tempAverages[tempRequestedStandartEditing]=aver;
tempStandarts[tempRequestedStandartEditing]=0;
tempRequestedStandartEditing=1;//now ready to ask the weight of 1st standart
resetTempGramsFromStandartEditing();
delay(789);
callibrStep=4;
selectCallibrating();
}
}
void run4CallibratingStep(){
if(but4JustPressed()){
last4Pressed=millis();
}
else if(but4JustReleased()){
if(millis()-last4Pressed>333){
tempGrams[tempGramsDigitEditing]++;
if(tempGrams[tempGramsDigitEditing]>9){
tempGrams[tempGramsDigitEditing]=0;
}
lcd.setCursor(6+tempGramsDigitEditing,1);
lcd.print(tempGrams[tempGramsDigitEditing]);
lcd.setCursor(6+tempGramsDigitEditing,1);
}
else{
tempGramsDigitEditing++;
if(tempGramsDigitEditing>5){
tempGramsDigitEditing=0;
}
lcd.setCursor(6+tempGramsDigitEditing,1);
}
}
else if(but2JustPressed()){
last2Pressed=millis();
}
else if(but2JustReleased()){
int i=0;long val=0;
while(i<5){val+=tempGrams[i];val*=10;++i; }
val+=tempGrams[i];
if(val>0){
int j=0;
while(j<tempRequestedStandarts){
if(j!=tempRequestedStandartEditing){
if(tempStandarts[j]>0){
if(tempStandarts[j]==val){
break;///already setted....not allows same
}
}
}
++j;
}
if(j==tempRequestedStandarts){
//onl("procced with the editing weight as standart ",val);
tempStandarts[tempRequestedStandartEditing]=val;
computeAverage(tempSampling);
tempAverages[tempRequestedStandartEditing]=aver;
if(tempRequestedStandartEditing < tempRequestedStandarts){
//onl("going to next ",tempRequestedStandartEditing," / ",tempRequestedStandarts);
tempRequestedStandartEditing++;
resetTempGramsFromStandartEditing();
tempGramsDigitEditing=5;//goes to grams position
selectCallibrating();
}
else{
//ons("callibration finished !!!");
//printTempArrays();
//ons("Must first sort standarts");
lcd.clear();
lcd.print(F("sorting and"));
lcd.setCursor(0,1);
lcd.print("updating eep+ROM");
sortInsertionTempArrays();
//printTempArrays();
//ons("storing to ram");
storeTempArraysToRam();
updateEEPROMforHX711Datautils();
delay(1234);
callibrStep=0;
rollOption();//leave to see the things
}
}
else{
//oni("",val," Already declared at : ",j);
lcd.clear();
lcd.print(val);
lcd.print(F(" Already"));
lcd.setCursor(0,1);
lcd.print(F("declared @ "));
lcd.print(j);
delay(1234);
selectCallibrating();
}
}
else{
//ons("zero not acceptable");
lcd.clear();
lcd.print(F("Zero not accept"));
delay(1234);
selectCallibrating();
}
}
}
void storeTempArraysToRam(){
int i=0,l=tempRequestedStandarts+1;
LoadsUsing=l;
while(i<l){
LoadsStandarts[i]=tempStandarts[i];
LoadsSamplesAverage[i]=tempAverages[i];
//onl("i: ",i," st=",LoadsStandarts[i]," av=",LoadsSamplesAverage[i]);
++i;
}
while(i<10){
LoadsStandarts[i]=0;
LoadsSamplesAverage[i]=0;
//onl("i: ",i," st=",LoadsStandarts[i]," av=",LoadsSamplesAverage[i]);
++i;
}
}
void sortInsertionTempArrays(){
int i, j;
int n=tempRequestedStandarts+1;
long key,followKey;
for (i = 1; i < n; i++) {
key = tempStandarts[i];
followKey = tempAverages[i];
j = i - 1;
while (j >= 0 && tempStandarts[j] > key) {
tempStandarts[j+1] = tempStandarts[j];
tempAverages[j+1] = tempAverages[j];
j = j - 1;
}
tempStandarts[j + 1] = key;
tempAverages[j+1] = followKey;
}
}
Δεν υπάρχουν σχόλια:
Δημοσίευση σχολίου