Error Rotary Encoder Reading

Dear all,

I have problem when creating a program in arduino uno. I want to combine between reading a rotary encoder (omron model E6B2 CWZ3E 2000 omron model E6B2 CWZ3E 2000 p/r ) and reading a temperature sensor (DS18S20).

I tried using example in playground.arduino.cc to test separately between rotary encoder and DS18S20 and It successful. I used this code to test rotary encoder:

/* NOTES
1. This program without interupt, but OK
2. source: http://playground.arduino.cc/Main/RotaryEncoders
*/

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 7, 6, 5, 4);

int val; 
int encoder0PinA = 2;
int encoder0PinB = 3;
int encoder0Pos = 0;
int encoder0PinALast = LOW;
int n = LOW;

void setup() { 
  pinMode (encoder0PinA,INPUT);
  pinMode (encoder0PinB,INPUT);
  Serial.begin (9600);
  Serial.println(" ");                
  Serial.println("Bismillaah... begin reading encoder"); 
  Serial.println("diambil dari file _3__encoder.ino");
  lcd.begin(16, 2);
  lcd.setCursor(0, 0); lcd.print("Bismillah ...");
  lcd.setCursor(0, 1); lcd.print("3_encoder.ino");
  delay(1000);  
  lcd.setCursor(0, 1); lcd.print("Encoder 2014");
  delay(1000);
  lcd.setCursor(0, 0); lcd.print("--Read Encoder--"); 
} 

 void loop() { 
   n = digitalRead(encoder0PinA);
   if ((encoder0PinALast == LOW) && (n == HIGH)) {
     if (digitalRead(encoder0PinB) == LOW) {
       encoder0Pos--;
     } else {
       encoder0Pos++;
     }
     Serial.print(encoder0Pos);
     Serial.print("/");
     lcd.setCursor(0, 1); lcd.print("               ");  
     lcd.setCursor(5, 1); lcd.print(encoder0Pos);
   } 
    encoder0PinALast = n;
 }

It works. The result from that program, if I turn the encoder, it show integer.

Then I used this code below to combine rotary encoder with temperature sensor.

/* NOTES
1. This program without interupt, but OK
2. source: http://playground.arduino.cc/Main/RotaryEncoders
3. source: http://playground.arduino.cc/Learning/OneWire
*/


#include <OneWire.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 7, 6, 5, 4);

//Temperature chip i/o
int DS18S20_Pin = 8; //DS18S20 Signal pin on digital 2
OneWire ds(DS18S20_Pin);  // on digital pin 2

byte SimbolDerajat[8] = {6,9,9,6,0,0,0};
//byte SimbolDerajat[8] = {0,10,31,31,14,4,0};

int val; 
int encoder0PinA = 2;
int encoder0PinB = 3;
int encoder0Pos = 0;
int encoder0PinALast = LOW;
int n = LOW;

void setup(void) { 
  pinMode (encoder0PinA,INPUT);
  pinMode (encoder0PinB,INPUT);
  Serial.begin (9600);
  Serial.println(" ");
  Serial.println("Bismillaah... begin reading encoder and DS18S20");
  Serial.println("diambil dari file _4__encoder_DS.ino");
  lcd.begin(16, 2);
  lcd.createChar(0, SimbolDerajat);
  lcd.setCursor(0, 0); lcd.print("Bismillah ...");
  lcd.setCursor(0, 1); lcd.print("4_encoder_DS.ino");
  delay(1000);  
  lcd.setCursor(0, 1); lcd.print("Encoder and Temp");
  delay(1000);
  lcd.clear();
} 

 void loop() {
   n = digitalRead(encoder0PinA);
   if ((encoder0PinALast == LOW) && (n == HIGH)) {
     if (digitalRead(encoder0PinB) == LOW) {
       encoder0Pos--;
     } else {
       encoder0Pos++;
     }
     lcd.setCursor(0, 0);  lcd.print("Putar: ");
     lcd.print(encoder0Pos);  lcd.print("    ");
     Serial.print("Putaran: ");
     Serial.print(encoder0Pos); Serial.print(". ");
   } 
    encoder0PinALast = n;
//   int putar = getEncoder();
   float suhu = getTemp();
   lcd.setCursor(0, 1);  lcd.print("Suhu: ");
   lcd.print(suhu,1); lcd.print(" ");
   lcd.write((uint8_t)0); lcd.print("C");
   Serial.print("Suhu: ");
   Serial.print(suhu); Serial.println(" deg C");
 //  delay(100); //just here to slow down the output so it is easier to read  
 } 

int getEncoder(){
   n = digitalRead(encoder0PinA);
   if ((encoder0PinALast == LOW) && (n == HIGH)) {
     if (digitalRead(encoder0PinB) == LOW) {
       encoder0Pos--;
     } else {
       encoder0Pos++;
     }
   } 
    encoder0PinALast = n;
    return encoder0Pos;
}

 float getTemp(){
  //returns the temperature from one DS18S20 in DEG Celsius
  byte data[12];
  byte addr[8];
  if ( !ds.search(addr)) {
      //no more sensors on chain, reset search
      ds.reset_search();
      return -1000;
  }
  if ( OneWire::crc8( addr, 7) != addr[7]) {
      Serial.println("CRC is not valid!");
      return -1000;
  }
  if ( addr[0] != 0x10 && addr[0] != 0x28) {
      Serial.print("Device is not recognized");
      return -1000;
  }
  ds.reset();
  ds.select(addr);
  ds.write(0x44,1); // start conversion, with parasite power on at the end

  byte present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE); // Read Scratchpad

  
  for (int i = 0; i < 9; i++) { // we need 9 bytes
    data[i] = ds.read();
  }
  
  ds.reset_search();
  
  byte MSB = data[1];
  byte LSB = data[0];

  float tempRead = ((MSB << 8) | LSB); //using two's compliment
  float TemperatureSum = tempRead / 16;
  
  return TemperatureSum;
}

The result, when I turn the rotary encoder, the LCD show integer, but not simultaneously;…

Could you help my problem?
Thank you for your attention…

regards

when I turn the rotary encoder, the LCD show integer, but not simultaneously

What two actions are supposed to take place simultaneously? As it is, the LCD should show the encoder position only when an encoder transition occurs.

Sometimes I turn the encoder then the LCD show an encoder transition, but another time, I turn the encoder then the value shown at LCD not change..

The code can only detect a rising edge transition on the A encoder pin (out of four possible transitions). Is that what you mean?

You are reading the temperature each time through the loop. The data sheet indicates that the DS18S20 is 12 bit conversion and can take up to 750 ms. You have other commands in your function as well. You might try place some millis timers around the call for getTemp() to see how long it takes. I think you may be missing encoder counts while you are off getting temperature.

You may want to test this by putting the temperature reads on a timer, rather than each time through the loop and see if the encoder counts increment as expected when there is not a temperature conversion going on. Reading and displaying the temperature every time through the loop seems excessive. Furthermore, unchanging aspects of your display should not be rewritten each pass through the loop.

You may want to convert the encoder read to an interrupt driven routine, but I am not sure if the reading of the DS18S20 is blocking or not.

thank you for your explanation...

May you give suggestion, what sensor should I use? I want to measure water temperature...

My friend say: "use thermocouple", but my question, how to read thermocouple via arduino uno R3??

Google "Arduino thermocouple" for lots of suggestions on how to read a thermocouple. Doing so will require external circuitry.

Edit: I believe that as it is now written, the code is blocking during temperature conversion. However, there is no reason to wait for the conversion to finish. Read up on how to do that here: http://playground.arduino.cc/Learning/OneWire

Jim has pointed you towards non blocking code.

If you do require a hardware change, there are a few other alternatives to thermocouples. It appears you need a waterproof probe for your application.

The DS18B20 is the successor to the DS18S20 and can be configured for 9, 10, 11, or 12 bit conversion. The 9 bit is very much faster, and may provide adequate temperature resolution for you application. It is readily available in a probe.

You may be able to find a linear analog sensor like the TMP 36 or LM 35 in a probe configuration. They are simple to use with an Arduino.

There are many choices of NTC thermistors in probe configurations, but they are non linear and will require using a conversion formula.