Κυριακή 23 Αυγούστου 2020

My first Arduino Scale-Zygaria 10kg with LCD(i2c) Dht and 3 buttons Callibratable using 81 bytes EEPROM













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;

    }  

}

Τετάρτη 12 Αυγούστου 2020

Arduino Absolute Rotary Encoder Bourns EAW ACE-128

Absolute Rotary Encoder 
EAW0J-B24-AE0128L 

128 positions (clicks) but hard to turn vs KY-040...... 
Arduino code (no i2c ... no library )








The ino file
----------------------------

//https://www.bourns.com/docs/product-datasheets/ace.pdf?sfvrsn=2abe8ff1_3
/*
Bit/Pin correlation: b7 b6 b5 b4 b3 b2 b1 b0 = p8 p7 p6 p5 p4 p3 p2 p1
A binary “1” denotes an “open” switch and a binary “0” denotes a “closed” switch.
Positions 0-127 are seen by a clockwise rotation of the shaft.
 */

 
//On Arduino ground the (left) C pin of the Rotary Encoder
 (between 2 and 3 pin of encoder) 

//your pin arrangement here
const uint8_t rpin1=4;
const uint8_t rpin2=5;
const uint8_t rpin3=6;
const uint8_t rpin4=7;
const uint8_t rpin5=8;
const uint8_t rpin6=9;
const uint8_t rpin7=10;
const uint8_t rpin8=11;
/*use uint8_t and int for return as from 
//hardware/arduino/avr/cores/arduino/wiring_digital.c      
//int digitalRead(uint8_t pin)
*/
int bit0;
int bit1;
int bit2;
int bit3;
int bit4;
int bit5;
int bit6;
int bit7;

//bit7,bit6,bit5,bit4,bit3,bit2,bit1,bit0
int allBitsAsInt;

int rotaryPreviusPosition=-1;
int rotaryCurrentPosition;


//PROGMEM??
const uint8_t encoderMap_12345678[256] = {
  0xFF,0x38,0x28,0x37,0x18,0xFF,0x27,0x34,0x08,0x39,0xFF,0xFF,0x17,0xFF,0x24,0x0D,
  0x78,0xFF,0x29,0x36,0xFF,0xFF,0xFF,0x35,0x07,0xFF,0xFF,0xFF,0x14,0x13,0x7D,0x12,
  0x68,0x69,0xFF,0xFF,0x19,0x6A,0x26,0xFF,0xFF,0x3A,0xFF,0xFF,0xFF,0xFF,0x25,0x0E,
  0x77,0x76,0xFF,0xFF,0xFF,0x6B,0xFF,0xFF,0x04,0xFF,0x03,0xFF,0x6D,0x6C,0x02,0x01,
  0x58,0xFF,0x59,0xFF,0xFF,0xFF,0xFF,0x33,0x09,0x0A,0x5A,0xFF,0x16,0x0B,0xFF,0x0C,
  0xFF,0xFF,0x2A,0x2B,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x15,0xFF,0x7E,0x7F,
  0x67,0xFF,0x66,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x5B,0xFF,0xFF,0xFF,0xFF,0xFF,
  0x74,0x75,0xFF,0xFF,0x73,0xFF,0xFF,0xFF,0x5D,0x5E,0x5C,0xFF,0x72,0x5F,0x71,0x00,
  0x48,0x47,0xFF,0x44,0x49,0xFF,0xFF,0x1D,0xFF,0x46,0xFF,0x45,0xFF,0xFF,0x23,0x22,
  0x79,0xFF,0x7A,0xFF,0x4A,0xFF,0xFF,0x1E,0x06,0xFF,0x7B,0xFF,0xFF,0xFF,0x7C,0x11,
  0xFF,0xFF,0xFF,0x43,0x1A,0xFF,0x1B,0x1C,0xFF,0x3B,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F,
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x05,0xFF,0xFF,0xFF,0x6E,0xFF,0x6F,0x10,
  0x57,0x54,0xFF,0x2D,0x56,0x55,0xFF,0x32,0xFF,0xFF,0xFF,0x2E,0xFF,0xFF,0xFF,0x21,
  0xFF,0x53,0xFF,0x2C,0x4B,0xFF,0xFF,0x1F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x20,
  0x64,0x3D,0x65,0x42,0xFF,0x3E,0xFF,0x31,0x63,0x3C,0xFF,0x2F,0xFF,0xFF,0xFF,0x30,
  0x4D,0x52,0x4E,0x41,0x4C,0x3F,0xFF,0x40,0x62,0x51,0x4F,0x50,0x61,0x60,0x70,0xFF };


void readRotaryCurrentPosition(){
  bit0=digitalRead(rpin1);
  bit1=digitalRead(rpin2);
  bit2=digitalRead(rpin3);
  bit3=digitalRead(rpin4);
  bit4=digitalRead(rpin5);
  bit5=digitalRead(rpin6);
  bit6=digitalRead(rpin7);
  bit7=digitalRead(rpin8);

  allBitsAsInt = bit7;
  allBitsAsInt <<= 1 ; allBitsAsInt += bit6;
  allBitsAsInt <<= 1 ; allBitsAsInt += bit5;
  allBitsAsInt <<= 1 ; allBitsAsInt += bit4;
  allBitsAsInt <<= 1 ; allBitsAsInt += bit3;
  allBitsAsInt <<= 1 ; allBitsAsInt += bit2;
  allBitsAsInt <<= 1 ; allBitsAsInt += bit1;
  allBitsAsInt <<= 1 ; allBitsAsInt += bit0;

  rotaryCurrentPosition=encoderMap_12345678[allBitsAsInt];  
}

void printForDebug(){// "Endianness" .... little?
    Serial.print("( ");
    Serial.print(bit7);Serial.print(" , ");
    Serial.print(bit6);Serial.print(" , ");
    Serial.print(bit5);Serial.print(" , ");
    Serial.print(bit4);Serial.print(" , ");
    Serial.print(bit3);Serial.print(" , ");
    Serial.print(bit2);Serial.print(" , ");
    Serial.print(bit1);Serial.print(" , ");
    Serial.print(bit0);Serial.print(" ) ");
  
    
    Serial.print("allBitsAsInt= ");
    Serial.print(allBitsAsInt);
    Serial.print(" -> ");
    Serial.print(rotaryCurrentPosition);
    Serial.println();
  
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(rpin1,INPUT_PULLUP);
  pinMode(rpin2,INPUT_PULLUP);
  pinMode(rpin3,INPUT_PULLUP);
  pinMode(rpin4,INPUT_PULLUP);
  pinMode(rpin5,INPUT_PULLUP);
  pinMode(rpin6,INPUT_PULLUP);
  pinMode(rpin7,INPUT_PULLUP);
  pinMode(rpin8,INPUT_PULLUP);

  // really need this ?
  rotaryPreviusPosition=-1;
  readRotaryCurrentPosition();
}

void loop() {

  readRotaryCurrentPosition();
  if(rotaryPreviusPosition!=rotaryCurrentPosition){
    rotaryPreviusPosition=rotaryCurrentPosition;
    //printForDebug();
    Serial.println(rotaryCurrentPosition);
  }
  else{
    //Serial.println("user didnt turn the encoder");
  }

  delay(10);
}//end loop



Παρασκευή 7 Αυγούστου 2020

Arduino KY-040 Rotary Encoder

 //No interruptions,no use switch pin

const int CLKpin = 4;  

const int DTpin = 5; 

//const int SWpin = 6; 


int clk=0;

int dt=0;

//int sw=0;


int prevclk=0;

//int prevdt=0;

//int prevsw=0;


void readCLK(){

  prevclk=clk;

  clk=digitalRead(CLKpin);

}

void readDT(){

  //prevdt=dt;

  dt=digitalRead(DTpin);

}

//void readSW(){prevsw=sw;sw=digitalRead(SWpin);}

int rotaryPosition = 0; 


//KY-040

int rotaryType=30; 

long rotaryBaudMinSuccesfullTested=57600;


void initRotaryEncoder(){

  pinMode (CLKpin,INPUT);

  pinMode (DTpin,INPUT);  

}

void resetRotaryPosition(){

  rotaryPosition = 0;  

  readCLK();

  Serial.println("Position Reseted to 0");  

}

void detectAndRefreshRotaryPosition(){

    readCLK();

    if (clk != prevclk){

        readDT();

        if (dt != clk){

          rotaryPosition ++;

          Serial.print ("Right to :");

        }

        else {

          rotaryPosition--;

          Serial.print("Left to: ");

        }

        rotaryPosition%=rotaryType;

        Serial.println(rotaryPosition);

     } 

 }




void setup() { 

  initRotaryEncoder();

  Serial.begin (rotaryBaudMinSuccesfullTested);

  resetRotaryPosition();

}

void loop() { 

detectAndRefreshRotaryPosition();

}


Παρασκευή 14 Φεβρουαρίου 2020

Point JTextField Java


This is an old and 'private' version so you cant easy understand 

See newer,simplest and standalone version 


---------------------------------------------------------------------------



Αντι να εχω 2 JTextField s

για να κουναω ενα Point με
το πληκτρολογιο,,,,

εχω 1 με ποντικι (και πληκτρα) !
------------------------








/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package jim.lib.j;

import java.awt.Color;
import java.awt.Cursor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Point2D;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import jim.Jim;
import jim.lib.a.Dmtn;
import jim.lib.a.Thr;
import jim.lib.d.Path;
import jim.lib.d.Point;
import jim.lib.j.swing.Jfr;
import jim.lib.j.swing.Jspl;
import jim.lib.j.swing.Jtf;
import jim.lib.j.swing.Manager;
import jim.lib.p.PaintNode;

/**
 * created at 14 Φεβ 2020
 * @author jimakoskx
 */
public class JArrows4Tf extends Jtf{
   
    public static void main(String[] args) {
        JArrows4Tf test1=new JArrows4Tf(1,2);
        JArrows4Tf test2=new JArrows4Tf(1.0,3.0,-10,10,1);
        test1.isReversingPaintMode=false;
        test2.isReversingPaintMode=true;
        test1.setName("test1");
        test2.setName("test2");
        test1.cutTextToLong=true;


       
        Jfr jfr=new Jfr(new Jspl(1,test1,test2).q(0.5).qCont());
        jfr.setBounds(0,0,888,222);
    }
   
    static ComponentListener CML=new ComponentListener() {
        @Override
        public void componentResized(ComponentEvent e) {
            JArrows4Tf src=(JArrows4Tf)e.getComponent();
            if(src!=null){src.resizedArrows4Tf();}
        }
        @Override
        public void componentMoved(ComponentEvent e) {
            JArrows4Tf src=(JArrows4Tf)e.getComponent();
            if(src!=null){src.movedArrows4Tf();}
        }

        @Override
        public void componentShown(ComponentEvent e) {
            JArrows4Tf src=(JArrows4Tf)e.getComponent();
            if(src!=null){src.shownArrows4Tf();}
        }

        @Override
        public void componentHidden(ComponentEvent e) {
            JArrows4Tf src=(JArrows4Tf)e.getComponent();
            if(src!=null){src.hiddenArrows4Tf();}
        }
    };
    static MouseMotionListener MML=new MouseMotionListener() {
        @Override
        public void mouseDragged(MouseEvent e) {
            JArrows4Tf src=(JArrows4Tf)e.getComponent();
            if(src!=null){src.draggedArrows4Tf(e);}
        }

        @Override
        public void mouseMoved(MouseEvent e) {
            JArrows4Tf src=(JArrows4Tf)e.getComponent();
            if(src!=null){src.movedArrows4Tf(e);}
        }
    };
    static MouseListener ML=new MouseListener() {
        @Override
        public void mouseClicked(MouseEvent e) {
            JArrows4Tf src=(JArrows4Tf)e.getComponent();
            if(src!=null){src.clickedArrows4Tf(e);}
        }
        @Override
        public void mousePressed(MouseEvent e) {
            JArrows4Tf src=(JArrows4Tf)e.getComponent();
            if(src!=null){src.pressedArrows4Tf(e);}
        }
        @Override
        public void mouseReleased(MouseEvent e) {
            JArrows4Tf src=(JArrows4Tf)e.getComponent();
            if(src!=null){src.releasedArrows4Tf(e);}
        }

        @Override
        public void mouseEntered(MouseEvent e) {
            JArrows4Tf src=(JArrows4Tf)e.getComponent();
            if(src!=null){src.enteredArrows4Tf(e); }
        }
        @Override
        public void mouseExited(MouseEvent e) {
            JArrows4Tf src=(JArrows4Tf)e.getComponent();
            if(src!=null){src.exitedArrows4Tf(e);}
        }
    };

    static KeyListener KL=new KeyListener() {
        @Override
        public void keyTyped(KeyEvent e) {}
        @Override
        public void keyPressed(KeyEvent e) {//System.out.println("shifter");
            JArrows4Tf src=(JArrows4Tf)e.getComponent();
            if(src!=null){src.klcheckingOneByShift(e);}
        }
        @Override
        public void keyReleased(KeyEvent e) {
            JArrows4Tf src=(JArrows4Tf)e.getComponent();
            if(src!=null){src.klcheckingOneByShift(e);}
        }
    };
    static KeyListener KLparser=new KeyListener() {
        @Override
        public void keyTyped(KeyEvent e) {}
        @Override
        public void keyPressed(KeyEvent e) {//System.out.println("parser");
            if(e.getKeyCode()==KeyEvent.VK_ENTER){
                JArrows4Tf src=(JArrows4Tf)e.getComponent();
                if(src!=null){src.parseText();}
            }
        }
        @Override
        public void keyReleased(KeyEvent e) {}
    };
   
    /**
     * need low Alpha for the text of JTextField to be visible
     */
    static Color arrowsColorDefault=new Color(143,44,0,90);
   
   
    //System.out.println("l"+SwingConstants.LEFT);
    //System.out.println("r"+SwingConstants.RIGHT);
    //System.out.println("b"+SwingConstants.BOTTOM);
    //System.out.println("t"+SwingConstants.TOP);   
    static final int swUp1=1;
    static final int swLeft2=2;
    static final int swDown3=3;
    static final int swRight4=4;
    static final String swStr[]=new String[]{"Center","Up","Left","Down","Right"};
   
    static long sleepBetweenPointIncDecrCalls=50;//20 frames per second
    static Thr unicMouseTimeMover=new Thr(){
        @Override
        public void doWork() {
            JArrows4Tf src=(JArrows4Tf)workOn.getUserObject();
            //System.out.println("working on "+src.getName());
            while(src.draggedDir4>0){
                //System.out.println("calling for "+swStr[src.draggedDir4]);
                src.applyAgainCurrDirectionToPoint();
                sl(sleepBetweenPointIncDecrCalls);
            }
        }
    }.q("JArrows4Tf.unicMouseTimeMover");
   
    static{
        unicMouseTimeMover.start();
    }   
    ///////////////////////////////////////////////////////////////
    ///////  C L A S S       H E R E   ////////////////////////////
    ///////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////
   

    Point val=new Point(0,0);
    Point stepAbs=new Point(1,1);
    Point min=new Point(Jim.minlong,Jim.minlong);
    Point max=new Point(Jim.maxlong,Jim.maxlong);
    Point temp=new Point(0,0);
   
   
    Path pLeft=new Path();
    PaintNode pnLeft=new PaintNode(pLeft).qfill();
    Path pRight=new Path();
    PaintNode pnRight=new PaintNode(pRight).qfill();
    Path pUp=new Path();
    PaintNode pnUp=new PaintNode(pUp).qfill();
    Path pDown=new Path();
    PaintNode pnDown=new PaintNode(pDown).qfill();
    /**
     * if even w > h may need to draw arrows vertically (or opposite)...may dummy never be used
     */
    boolean isReversingPaintMode=false;
    /**
     * width , w/2 , w/3 , 2*(w/3)
     */
    int w,wd2,wd3,wd32;
    /**
     * height , h/2 , h/3 , 2*(h/3)
     */
    int h,hd2,hd3,hd32;
   
   
    /**
     * if(false) then arrows not showing if mouse is out of JTextField
     */
    boolean arrowsAlwaysOn=true;
    /**
     *  Up0,Left1,Down2,Right3 Point move modes
     */
    /**
     * updated direction on dragging (before releasing mouse button)
     */
    int draggedDir4=-1;
    /**
     * Triggering starts when user press mouse on JTextfield<br>
     * MouseMotionListener and KeyListener will be added
     * Buffer of the static Thread will be filled with a reference to this Object<br>
     */
    int pressedDir4=-1;
    /**
     * According of the mouse button for slow,normal,quick speed of the Point movement
     */
    int multiplier=1;
    /**
     * If user suddenly while moving the Point press shift then we must slow speed<br>
     * to be easy to adjust at exact point
     */
    boolean isShiftDown=false;
    /**
     * One instead of STEP....cancelling step that is usually adjusted with multiplier !
     */
    int one=1;
   
   
    Dmtn buttons=new Dmtn();//MultipliersPerButtons ..binary search just for 1,2,3 values? Answer:...Just easy programming

    /**
     *
     */
    public JArrows4Tf (){
        super("OLA KALA EDO ");
        //setCursor(Cursor.getDefaultCursor());//no text cursor
        setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));//


        painter=new PaintNode();
        painter.q(arrowsColorDefault);
        painter.add(pnDown);
        painter.add(pnLeft);
        painter.add(pnRight);
        painter.add(pnUp);
       
       
        buttons.abin(MouseEvent.BUTTON1).crad(1);
        //buttons.abin(MouseEvent.BUTTON2).crad(1);
        buttons.abin(MouseEvent.BUTTON3).crad(3);
       
       
        addComponentListener(CML);
        addKeyListener(KLparser);
        addMouseListener(ML);
        refreshText();
    }
   
    public JArrows4Tf (double x,double y){
        this();
        val.x=x;
        val.y=y;
        refreshText();
    }
    public JArrows4Tf (double x,double y,double minv,double maxv,double stepv){
        this();
        if( stepv<=0 || (minv>=maxv) || x<minv || y<minv || x>maxv || y>maxv || (maxv-minv<stepv) ){
            throw new IllegalArgumentException("JArrows4Tf NOT if( step<=0 || (min>=max) || x<min || y<min || x>max || y>max || (max-min<step) )");
        }     
        val.x=x;
        val.y=y;
       
        min.x=minv;
        min.y=minv;
       
        max.x=maxv;
        max.y=maxv;
       
        stepAbs.x=stepv;
        stepAbs.y=stepv;
       
        refreshText();
    }
   
   
   
   
   
    /**
     * Override to notify for the new Point
     */
    public void xyChanged(){
        //System.out.println("must implement by class programmer user");
    }
    /**
     * Check limits and if ok sets and calls valuesChanged()
     * @param x
     * @param y
     * @return
     */
    public boolean setxy(double x,double y){
        if( x<min.x || x>max.x || y<min.y || y>max.y  ){
            return false;
        }
        else{
            val.x=x;
            val.y=y;
            xyChanged();
            refreshText();
            return true;
        }
    }
    public void setxyNoCheck(double x,double y){
        val.x=x;
        val.y=y;
        xyChanged();
        refreshText();
    }
    public void setxNoCheck(double x){
        val.x=x;
        xyChanged();
        refreshText();
    }
    public void setyNoCheck(double y){
        val.y=y;
        xyChanged();
        refreshText();
    }

    public boolean checkxy(double x,double y){
        return !( x<min.x || x>max.x || y<min.y || y>max.y );
    }
    public boolean checkx(double x){
        return !( x<min.x || x>max.x);
    }
    public boolean checky(double y){
        return !( y<min.y || y>max.y );
    }

   
   
    public int xi(){return (int)val.x;}
    public int yi(){return (int)val.y;}
    public long xl(){return (long)val.x;}
    public long yl(){return (long)val.y;}
    public double x(){return val.x;}
    public double y(){return val.y;}
   
    public void getxy(Point2D p){
        p.setLocation(val.x,val.y);
    }
    synchronized void parseText(){
        String text=getText();
        Point p=new Point();
        Exception e=jim.lib.d.Point.parsePoint(text, p);
        if(e!=null){
            JOptionPane.showMessageDialog(this, e,"Unable to parse Point from Text",JOptionPane.INFORMATION_MESSAGE);
        }
        else{
            if(setxy(p.x,p.y)){
                //System.out.println("good");
            }
            else{
                JOptionPane.showMessageDialog(this, "attempted to set \n("+p.x+","+p.y+")\nNot allowed because of\nlimitations\n"+getLimitsText(),"Values out of limits",JOptionPane.INFORMATION_MESSAGE);
                refreshText();
            }
        }
    }
    public String getLimitsText(){
        return min.x+" <= x <= "+max.x+" \n"+min.y+" <= y <= "+max.y+" \n";
    }
   
    public void setArrowsPainting(boolean active){
        painter.childrenOn=active;
        repaint();
    }
    public boolean getArrowsPainting(){
        return painter.childrenOn;
    }
    public void setArrowsColor(Color c){
        painter.q(c);
        repaint();
    }

    @Override
    public void setEnabled(boolean enabled) {
        super.setEnabled(enabled);
        if(enabled){addMouseListener(ML);}
        else{removeMouseListener(ML);}
    }
   
   
   
   
    boolean isArrowsHorizontal(){
        if(w>=h){
            if(isReversingPaintMode){return false;}
            else{return true;}
        }
        else{
            if(isReversingPaintMode){return true;}
            else{return false;}
        }
    }
    void resizedArrows4Tf(){
        w=getWidth();
        h=getHeight();
        pDown.reset();
        pLeft.reset();
        pRight.reset();
        pUp.reset();
       
       
        wd2=w/2;
        hd2=h/2;
        wd3=w/3;
        wd32=wd3*2;
        hd3=h/3;
        hd32=hd3*2;

        if(w>=h){
            if(isReversingPaintMode){resetingPaintModeVertical();}
            else{resetingPaintModeHorizontal();}
        }
        else{
            if(isReversingPaintMode){resetingPaintModeHorizontal();}
            else{resetingPaintModeVertical();}
        }
    }
    void movedArrows4Tf(){}
    void shownArrows4Tf(){}
    void hiddenArrows4Tf(){}
   
    void resetingPaintModeHorizontal(){
        pDown.moveTo(wd2, h);
        pDown.lineTo(wd3, hd2);
        pDown.lineTo(wd32,hd2);
        pDown.closePath();

        pUp.moveTo(wd2, 0);
        pUp.lineTo(wd32, hd2-1);
        pUp.lineTo(wd3,hd2-1);
        pUp.closePath();

        pLeft.moveTo(0, hd2);
        pLeft.lineTo(wd3, h);
        pLeft.lineTo(wd3,0);
        pLeft.closePath();

        pRight.moveTo(w, hd2);
        pRight.lineTo(wd32, 0);
        pRight.lineTo(wd32,h);
        pRight.closePath();       
    }
    void resetingPaintModeVertical(){
        pDown.moveTo(wd2, h);
        pDown.lineTo(w, hd32);
        pDown.lineTo(0,hd32);
        pDown.closePath();

        pUp.moveTo(wd2, 0);
        pUp.lineTo(0, hd3);
        pUp.lineTo(w,hd3);
        pUp.closePath();

        pLeft.moveTo(0, hd2);
        pLeft.lineTo(wd2-1,hd32);
        pLeft.lineTo(wd2-1,hd3);
        pLeft.closePath();

        pRight.moveTo(w, hd2);
        pRight.lineTo(wd2, hd3);
        pRight.lineTo(wd2,hd32);
        pRight.closePath();       
    }
   
   
   
   
   
   
         
    int getDir4(int ex,int ey){
        if(isArrowsHorizontal()){//System.out.println("Arrows are horizontal");
            if(ex>wd32){//System.out.println("Right");
                return swRight4;
            }
            else if(ex<wd3){//System.out.println("Left");
                return swLeft2;
            }
            else{
                if(ey<hd2){//System.out.println("Up");
                    return swUp1;
                }
                else{//System.out.println("Down");
                    return swDown3;
                }
            }
        }
        else{//System.out.println("Arrows are vertical");
            if(ey>hd32){//System.out.println("Down");
                return swDown3;
            }
            else if(ey<hd3){//System.out.println("Up");
                return swUp1;
            }
            else{
                if(ex<wd2){//System.out.println("Left");
                    return swLeft2;
                }
                else{//System.out.println("Right");
                    return swRight4;
                }
            }
        }
    }
    void clickedArrows4Tf(MouseEvent e){}
    void pressedArrows4Tf(MouseEvent e){
       
        int but=e.getButton();
        Dmtn buttonNode=buttons.abn(but);
        if(buttonNode!=null){
            multiplier=buttonNode.dmtn(0).i();
           
            int ex=e.getX();
            int ey=e.getY();
            pressedDir4=getDir4(ex, ey);
            draggedDir4=pressedDir4;


            isShiftDown=e.isShiftDown();///means NO MULTIPLIER AT ALL ..ONE
            //System.out.println("Pressed "+swStr[pressedDir4]+" mult="+multiplier);

            unicMouseTimeMover.works.crad(this);
            unicMouseTimeMover.interrupt();
            addKeyListener(KL);
            addMouseMotionListener(MML);
        }
        //else{System.out.println("This button is not installed");}
   
    }
    void releasedArrows4Tf(MouseEvent e){
        draggedDir4=0;
        removeMouseMotionListener(MML);
        removeKeyListener(KL);
    }
    void enteredArrows4Tf(MouseEvent e){
        if(!arrowsAlwaysOn){setArrowsPainting(true);}
    }
    void exitedArrows4Tf(MouseEvent e){
        if(!arrowsAlwaysOn){setArrowsPainting(false);}
    }
    void draggedArrows4Tf(MouseEvent e){
       
        isShiftDown=e.isShiftDown();///means NO MULTIPLIER AT ALL ..ONE
       
        int refresh=getDir4(e.getX(), e.getY());
        if(refresh!=draggedDir4){
            draggedDir4=refresh;
            //System.out.println("Dir changed to "+swStr[draggedDir4]);
        }
       
    }
   
    void movedArrows4Tf(MouseEvent e){}
   
   
   
         


    void valuesChanged0(){
        refreshText();
        xyChanged();
    }
    boolean cutTextToLong=false;
    public String getPointText(){
        if(cutTextToLong){return (long)val.x+","+(long)val.y;}
        else{return val.x+","+val.y;}
    }
    void refreshText(){
        setText(getPointText());           
    }


    void klcheckingOneByShift(KeyEvent e) {
        isShiftDown=e.isShiftDown();
    }

   

    void beep(){
        Manager.beep();
    }

    void applyAgainCurrDirectionToPoint(){
        //System.out.println("Going "+swStr[draggedDir4]);
        if(draggedDir4==swDown3){
            temp.y=val.y;
            if(isShiftDown){temp.y+=one;}
            else{temp.y+=stepAbs.y*multiplier;}
            if(temp.y>max.y){beep();}
            else{setyNoCheck(temp.y);}
        }
        else if(draggedDir4==swLeft2){
            temp.x=val.x;
            if(isShiftDown){temp.x-=one;}
            else{temp.x-=stepAbs.x*multiplier;}
            if(temp.x<min.x){beep();}
            else{setxNoCheck(temp.x);}
        }
        else if(draggedDir4==swRight4){
            temp.x=val.x;
            if(isShiftDown){temp.x+=one;}
            else{temp.x+=stepAbs.x*multiplier;}
            if(temp.x>max.x){beep();}
            else{setxNoCheck(temp.x);}
        }
        else if(draggedDir4==swUp1){
            temp.y=val.y;
            if(isShiftDown){temp.y-=one;}
            else{temp.y-=stepAbs.y*multiplier;}
            if(temp.y<min.y){beep();}
            else{setyNoCheck(temp.y);}           
        }
        //else{System.out.println("error 0...expecting 1,2,3,4");}
    }   
   
   
   
   
   
}

Τρίτη 15 Οκτωβρίου 2019

Java PreOrder Backward Enumeration Iterator

<svg width="100" height="100">
  <circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow" />
</svg>


/*First class on university...6/10 !!!*/
package dim.ds;

import dim.ext.javax.swing.tree.Dmtn;//DefaultMutableTreeNode
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Vector;

/**
NOT return ROOT !

 * A Backward Pre Order Enumeration

 * <br>7, 6, 999, 99, some, 3, 2, 1
 * <br> will be given by the following tree
 * <br>0=root
 * <br>--0.1=1
 * <br>--0.2=2
 * <br>--0.3=3
 * <br>--------0.3.0=some
 * <br>----------------0.3.0.0=99
 * <br>----------------0.3.0.1=999
 * <br>--------0.3.1=6
 * <br>--0.4=7
 * @author jimidimi
 */
public class PreBackOrder implements Enumeration<Dmtn>,Iterator<Dmtn>{
    public static void main(String[] args) {
        Dmtn t=new Dmtn("root");
        //7,6,1,2,5,3,2,1
        t.crad(1);
        t.crad(2);
        Dmtn d3=t.crad(3);
            Dmtn d5=d3.crad(5);
                d5.crad(2);
                d5.crad(1);
            Dmtn d6=d3.crad(6);
        t.crad(7);
     
        PreBackOrder pbo=new PreBackOrder(t);
        while(pbo.hasMoreElements()){
            Object o=pbo.nextElement();
            System.out.println(pbo.counter+" : "+o+"  depth = "+pbo.depth);
        }
     
        System.out.println(" -------------- second example ----------- ");
        t.removeAllChildren();
     
        //
        //4,0,450,3,2,1,21
        t.sbad(21).sbad(1);
        t.sbad(21).sbad(2);
        t.sbad(21).sbad(3);
        t.sbad(450).sbad(0);
        t.sbad(450).sbad(4);

     
        pbo.clear();
        while(pbo.hasMoreElements()){
            Object o=pbo.nextElement();
            System.out.println(pbo.counter+" : "+o+"  depth = "+pbo.depth);
        }
     
     
     
    }
 
 
 
 
 
    public Dmtn root,par,it;
 
    /**
     * The current index path
     */
    public Vector<Integer> indexPathStack=new Vector<>();
    /**
     * The current last index of Vector
     */
    public int stackIndex=-1;
    /**
     * The current last Value of Vector
     */
    public int itIndexOnPar;
 
    /**
     * Simple enumeration step counter
     */
    public int counter=-1;
 
 
    /**
     * The previus (from call) stack.size()=stackIndex+1
     */
    int depth=0;

    /**
     *
     * @param theRoot to iterate without ... theRoot !
     * <br>To iterate also to Root use
     * <br>1.Or some level up root
     * <br>2.Or Dmtn temp=new Dmtn("temp");
     * <br>  temp.add(my_root);
     * <br>  new PreBackOrder(temp).iterate.....
     *
     */
    public PreBackOrder(Dmtn theRoot){
        root=theRoot;
        clear();
    }
    /**
     * When called must be synchronized(lock) ????
     */
    public void clear(){
        it=root;
        indexPathStack.clear();
        stackIndex=-1;
        int chc=it.getChildCount();
        itIndexOnPar=chc;
        while(chc>0){
            chc--;
            indexPathStack.add(chc);
            itIndexOnPar=chc;
            ++stackIndex;
            it=it.dmtn(chc);
            chc=it.getChildCount();
        }
        par=it.pardmtn();
        counter=-1;
        depth=stackIndex+1;
    }
 


    @Override
    public boolean hasNext() {
        return it!=null;
    }
    @Override
    public Dmtn next() {
        return nextElement();
    }
 
    /**
     *
     * @return it!=null;
     */
    @Override
    public boolean hasMoreElements() {
        return it!=null;
    }
    /**
     * rolls on the iteration to next stage
     * @return
     */
    @Override
    public Dmtn nextElement() {
        ++counter;//info
        depth=stackIndex+1;//info
        ///////////////////////////////////////
        Dmtn out=it;
        //this missing TAB INSET is missing but class not return ROOT ????!!!???
            --itIndexOnPar;
            //System.out.println("lastchc : "+lastChc);
            indexPathStack.setElementAt(itIndexOnPar, stackIndex);
            //System.out.println(""+itIndex);
            if(itIndexOnPar>=0){
                //System.out.println("Taking brother");
                it=par.dmtn(itIndexOnPar);
                int chc=it.getChildCount();
                while(chc>0){
                    chc--;
                    indexPathStack.add(chc);
                    itIndexOnPar=chc;
                    ++stackIndex;
                    it=it.dmtn(chc);
                    chc=it.getChildCount();
                }
                par=it.pardmtn();
            }
            else{
                //System.out.println("Finished iterate on "+par+" children");
             
                indexPathStack.remove(stackIndex);
                --stackIndex;

                if(stackIndex<0){
                    it=null;
                }
                else{
                    it=par;
                    par=it.pardmtn();
                    itIndexOnPar=indexPathStack.get(stackIndex);
                }
             
            }
        return out;
    }


 
 
 
 
 
 
}

Java Scan-Sarosi- Util Class

Java Scan-Sarosi- Util Class

package dim.games.streetracing;

import dim.ext.java.awt.Erect;

//erase also SarosiBuild class......
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JSlider;
import javax.swing.JSpinner;
import javax.swing.JSplitPane;
import javax.swing.SpinnerNumberModel;







/**
 *
 * @author jimidimi
 */
public class Sarosi extends Erect{//Rectangle
   
    public static void main(String[] args) {
        SarosiBuild.testBuild();
    }


    /**
     * current iterator indexes setted before scan() being called
     */
    public int xScan,yScan;
   
    public int xLimit,yLimit;
    public int xDif=1,yDif=1;
    public int xOneOnly=0,yOneOnly=0;//when some dif=0
    public boolean xInnerWhile=true;
    public Sarosi(int x, int y, int width, int height) {
        super(x, y, width, height);
    }
   
   
   
   
    //OVERRIDE
    public void scan(){}
    public void scanAllFinished(){}
    public void scanAllStarting(){}
   
   


   
    //CLEARing mind

   
    public void scanAll(){
        scanAllStarting();
        if(xDif<0){
            if(yDif<0){//-1x,-1y
                if(xInnerWhile){
                    yScan=y+height-1;
                    yLimit=y-1;
                    xLimit=x-1;
                    int temp=x+width-1;
                    while(yScan>yLimit){
                        xScan=temp;
                        while(xScan>xLimit){scan();//////////////
                            xScan+=xDif;
                        }
                        yScan+=yDif;
                    }
                }
                else{
                    xScan=x+width-1;
                    xLimit=x-1;
                    yLimit=y-1;
                    int temp=y+height-1;
                    while(xScan>xLimit){
                        yScan=temp;
                        while(yScan>yLimit){scan();///////////////
                            yScan+=yDif;
                        }
                        xScan+=xDif;
                    }
                }               
            }
            else if(yDif>0){//-1x,+1y
                if(xInnerWhile){
                    yScan=y;
                    yLimit=y+height;
                    xLimit=x-1;
                    int temp=x+width-1;
                    while(yScan<yLimit){
                        xScan=temp;
                        while(xScan>xLimit){scan();///////////////////
                            xScan+=xDif;
                        }
                        yScan+=yDif;
                    }
                }
                else{
                    xScan=x+width-1;
                    xLimit=x-1;
                    yLimit=y+height;
                    while(xScan>xLimit){
                        yScan=y;
                        while(yScan<yLimit){scan();/////////////////////
                            yScan+=yDif;
                        }
                        xScan+=xDif;
                    }
                }               
            }
            else{//-1x,0y
                xScan=x+width-1;
                xLimit=x-1;
                yScan=yOneOnly;
                while(xScan>xLimit){
                    scan();
                    xScan+=xDif;
                }
               
            }
        }
        else if(xDif>0){
            if(yDif<0){//+1x,-1y
                if(xInnerWhile){
                    yScan=y+height-1;
                    yLimit=y-1;
                    xLimit=x+width;
                    while(yScan>yLimit){
                        xScan=x;
                        while(xScan<xLimit){scan();////////////////////////
                            xScan+=xDif;
                        }
                        yScan+=yDif;
                    }
                }
                else{
                    xScan=x;
                    xLimit=x+width;
                    yLimit=y-1;
                    int temp=y+height-1;
                    while(xScan<xLimit){
                        yScan=temp;
                        while(yScan>yLimit){scan();////////////////////
                            yScan+=yDif;
                        }
                        xScan+=xDif;
                    }
                }               

            }
            else if(yDif>0){//+1x,+1y
                if(xInnerWhile){//System.out.println("+1x,+1y,true");
                    yScan=y;
                    yLimit=y+height;
                    xLimit=x+width;
                    while(yScan<yLimit){
                        xScan=x;
                        while(xScan<xLimit){scan();//////////////////////
                            xScan+=xDif;
                        }
                        yScan+=yDif;
                    }
                }
                else{
                    xScan=x;
                    xLimit=x+width;
                    yLimit=y+height;
                    while(xScan<xLimit){
                        yScan=y;
                        while(yScan<yLimit){scan();////////////////////////
                            yScan+=yDif;
                        }
                        xScan+=xDif;
                    }
                }               
            }
            else{//1x,0y
                xScan=x;
                xLimit=x+width;
                yScan=yOneOnly;
                while(xScan<xLimit){
                    scan();
                    xScan+=xDif;
                }
            }
        }
        else{
            if(yDif<0){//0x-1y
                yScan=y+height-1;
                yLimit=y-1;
                xScan=xOneOnly;
                while(yScan>yLimit){
                    scan();
                    yScan+=yDif;
                }
            }
            else if(yDif>0){//0x+1y
                yScan=y;
                yLimit=y+height;
                while(yScan<yLimit){
                    scan();
                    yScan+=yDif;
                }
            }
            else{//0x 0y disabled?
                //System.out.println("Disabled all ? or just scan()");
                scan();//stupid
            }
           
        }
        scanAllFinished();

    }
   
   
   
   

   
}


class SarosiBuild{
    static int rows=3;
    static int cols=7;
    static JPanel jpGrid=new JPanel(new GridLayout(rows,cols));
    static JRadioButton comps[][]=new JRadioButton[rows][cols];
    static JSpinner jslXdif=new JSpinner(new SpinnerNumberModel(1,-101,101,1));
    static JSpinner jslYdif=new JSpinner(new SpinnerNumberModel(1,-101,101,1));
    static Sarosi testInit=new Sarosi(0,0,cols,rows){
        public void scan(){
            //System.out.println(xScan+" , "+yScan);
            comps[yScan][xScan]=new JRadioButton(xScan+" , "+yScan,false);
            jpGrid.add(comps[yScan][xScan]);
        }
    };
    static Sarosi testReset=new Sarosi(0,0,cols,rows){
        public void scan(){
            comps[yScan][xScan].setSelected(false);
        }
    };
    static Sarosi testAct=new Sarosi(0,0,cols,rows){
        public void scan(){
            comps[yScan][xScan].setSelected(true);
            Toolkit.getDefaultToolkit().beep();
            try{Thread.currentThread().sleep(500);}catch(InterruptedException inter){}
        }
    };

    static void testBuild(){
        JPanel jpButs=new JPanel(new GridLayout(4,1));
       
       
        JButton jbRestart=new JButton("Restart");
        jpButs.add(jbRestart);
       
       
        JPanel jpX=new JPanel(new BorderLayout());
        jpX.add(jslXdif,BorderLayout.CENTER);
        jpX.add(new JLabel(" X dif "),BorderLayout.WEST);
        jpButs.add(jpX);
       
        JPanel jpY=new JPanel(new BorderLayout());
        jpY.add(jslYdif,BorderLayout.CENTER);
        jpY.add(new JLabel(" Y dif "),BorderLayout.WEST);
        jpButs.add(jpY);

        JRadioButton jrbInnerWhile=new JRadioButton("X Inner While",true);
        jpButs.add(jrbInnerWhile);
       
       

       
        testInit.scanAll();
       
        JSplitPane jspl=new JSplitPane(1,jpButs,jpGrid);
       
       
       
        JFrame jfr=new JFrame("testing "+Sarosi.class);
        Dimension screen=Toolkit.getDefaultToolkit().getScreenSize();
        jfr.setBounds(screen.width/4,screen.height/4,screen.width/2,screen.height/2);
        jfr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jfr.getContentPane().add(jspl,BorderLayout.CENTER);
        jfr.setVisible(true);
       
        jbRestart.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                Thread thr=new Thread(){
                    public void run(){
                        testReset.scanAll();
                        try{Thread.currentThread().sleep(1234);}catch(InterruptedException inter){}
                        testAct.xDif=(Integer)jslXdif.getValue();
                        testAct.yDif=(Integer)jslYdif.getValue();
                        testAct.xInnerWhile=jrbInnerWhile.isSelected();
                        testAct.scanAll();
                       
                    }
                };
                thr.setDaemon(true);
                thr.start();
            }
        });
       
   
    }

}