Go Down

Topic: Timing issues with DS18B20 sensor and 4dig7segment display (multiplex+ shiftreg) (Read 925 times) previous topic - next topic

PaulRB

Quote
when I put 3 or 2 ms it starts scanning
Quote
2 ms is unoticable
Now I'm confused. Is it ok or not?

PaulRB

If it's still flickering every 750ms, I have a couple more ideas.

Switch to using SPI.transfer() instead of shiftOut(). This may mean changing pins.

Improve setDigits() by using dtostrf().

Moshtaraq

Now I'm confused. Is it ok or not?

I get your confusion, when you put 1 in the statement it waits til it's more than 1 so 2ms.... with 1 in the statement it doesn't scan.

Moshtaraq

If it's still flickering every 750ms, I have a couple more ideas.

Switch to using SPI.transfer() instead of shiftOut(). This may mean changing pins.

Improve setDigits() by using dtostrf().
I updated the code with your previous suggestions (the boolean values). And I must say there is an improvement on the time the display is dark, but there's still a flicker every 750ms, although faster. I'll look into SPI.transfer and dtostrf but a quick google made my jaw drop.....

Here is the improved code if you're interested or want implement those functions yourself or explain how I go about doing that. I prefer the latter.

Code: [Select]

#include <OneWire.h>
#include <DallasTemperature.h>
OneWire oneWire(2); //onewire pin selection
DallasTemperature sensors(&oneWire);//dallas temp lib sensor detection
DeviceAddress tempSensor = {0x28, 0xFF, 0xE7, 0xF3, 0x75, 0x18, 0x01, 0x24}; //adress of DS18B20


//shift register interfacing 74HC595N
int DS_pin = 8;
int latch_pin = 9;
int shift_pin = 10;

//reading maniupulation
float reading;
float readingten;
float tempC;
boolean tempRequest = 0;
unsigned long lastRequestTime = 0;


int const numOfDigits = 4;
int d1 = 5;   //1000
int d2 = 13;  //0100
int d3 = 11;  //0010
int d4 = 7;   //0001
int digitPins[numOfDigits] = {d1, d2, d3, d4};
int digits[numOfDigits] = {20, 20, 20, 20};

int const numOfDecimals = 1;
int const floatPoint = numOfDigits - 1 - numOfDecimals;

//reading interval
unsigned long lastReadingTime = 0;
const int processingTime = 750; //max as specified in datasheet (depends on resolution)


int const numOfOutputs = 7;
int outputPins[numOfOutputs] = {d1, d2, d3, d4, DS_pin, latch_pin, shift_pin};


//      AAAAA
//     F     B
//     F     B
//      GGGGG
//     E     C
//     E     C
//      DDDDD   DP

//{F, A, B, G, E, D, C, DP} for every number
const byte registers[21] = {
  B11101110,//0
  B00100010,//1
  B01111100,//2
  B01110110,//3
  B10110010,//4
  B11010110,//5
  B11011110,//6
  B01100010,//7
  B11111110,//8
  B11110110,//9
  B11101111,//0.
  B00100011,//1.
  B01111101,//2.
  B01110111,//3.
  B10110011,//4.
  B11010111,//5.
  B11011111,//6.
  B01100011,//7.
  B11111111,//8.
  B11110111,//9.
  B00000000//empty
};


void setup() {

  for (int i = 0; i < numOfOutputs; i++) {
    pinMode(outputPins[i], OUTPUT);
  }

  pinMode(DS_pin, OUTPUT);
  pinMode(latch_pin, OUTPUT);
  pinMode(shift_pin, OUTPUT);
  Serial.begin(9600);
  sensors.setWaitForConversion(false);
  sensors.setResolution(tempSensor, 10);//set resolution
}

void setDigits() {
  readingten = reading * (float)pow(10, numOfDecimals); //987.6 to 9876
  digits[0] = (((int)readingten) % 10000) / 1000;  //9
  digits[1] = (((int)readingten) % 1000) / 100;    //8
  digits[2] = (((int)readingten) % 100) / 10;      //7
  digits[3] = (((int)readingten) % 10) / 1;        //6

  digits[floatPoint] = digits[floatPoint] + 10; //puts decimalpoint on the digit left from the decimals

  int i = 0;
  while (digits[i] == 0 && i < (numOfDigits - 1)) {
    digits[i] = 20; //001.3 to 1.3 removes uneeded zeros, registe[20] is B00000000
    i++;
  }
}


byte writeDisplay() {
  static byte j;
  static unsigned long lastUpdate;

  if (millis() - lastUpdate >= 1) {
    digitalWrite(digitPins[j], HIGH); //unselect previous digit
    if (++j >= 4) j = 0;
    digitalWrite(latch_pin, LOW);// opens register and locks outputs
    shiftOut(DS_pin, shift_pin, LSBFIRST, registers[digits[j]]);
    digitalWrite(latch_pin, HIGH);//latches from register to outputs
    digitalWrite(digitPins[j], LOW); //selects new digit
    lastUpdate = millis();
    return 1;
  }
  else return 0;
}

void loop() {
  if (writeDisplay() == 1) {
    if ( tempRequest == 1) {
      sensors.requestTemperaturesByAddress(tempSensor); //read temps
      lastRequestTime = millis();
      tempRequest = 0;
    }
    if ( (millis() - lastRequestTime) > processingTime) {
      reading = sensors.getTempC(tempSensor);
      setDigits();
      tempRequest = 1;
    }
  }
}

PaulRB

Did you try my suggestion from post #13? i.e. comment out this line:
Code: [Select]
      //sensors.requestTemperaturesByAddress(tempSensor); //read temps
and change this line:
Code: [Select]
      reading = 12.3; //sensors.getTempC(tempSensor);
Do you still get the flicker every 750ms?

If no flicker, this tells you that the communications with the sensor are the cause.

If you still see the flicker, put these lines in setup()
Code: [Select]
      reading = 12.3;
      setDigits();

and comment out the call to setDigits() in loop().

If no flicker after that, this tells you the problem could be the setDigits() function. Restore the first two lines above but leave setDigits() commented out in loop().

If the flicker does not come back, that confirms the problem is setDigits().

Moshtaraq

Did you try my suggestion from post #13?
and comment out the call to setDigits() in loop().
Can not test it right now but can already tel its not the setDigits cause in have an other script where i do the setdigits every loop after reading an analog value from a potentiemeter.

Will test your commenting out strategy tomorrow.

PaulRB

I get your confusion, when you put 1 in the statement it waits til it's more than 1 so 2ms.... with 1 in the statement it doesn't scan.
Still confusing. The code says
Code: [Select]
 if (millis() - lastUpdate >= 1) {
so it doesn't wait until its more than 1. As soon as it equals 1, it moves to the next digit.

Moshtaraq

Oh didnt notice the = there, yeah I see a scanning thing when I put 2 there.

PaulRB

Can you please do the forum a favour? Stop hitting "Quote" when you reply. Hit "Reply" instead. Unless you want to refer to a short part of a previous post, then use "Quote" and delete out everything except the short part you want to ask about. Hitting "Quote" all the time just makes the thread twice as long to scroll through, but adds no value to the thread.

PaulRB

I see a scanning thing when I put 2 there.
That should not be. The display will be refreshed at 125 times per second. That's too fast to see.

PaulRB

its not the setDigits cause in have an other script where i do the setdigits every loop after reading an analog value from a potentiemeter.
If that's true, Mike was correct from the start. There's probably nothing you can do in the sketch to avoid the flicker. I suspect that using interrupts won't help, because the OneWire library probably disables interrupts so that they can't corrupt communications with the sensor. If that's true, your only choice will be to get another chip to do the multiplexing, such as max7219 or ht16k33.

Moshtaraq

Hi,

haven't been able to do anything for the last month. Was just reading up on this post again and have a question about workings of the MAX7219 IC Grumpy_mike suggested at the very start. If you give it the data to display, does it keep displaying it untill I give it a new 'frame'? e.g. if I give it 0123 to display it keeps that on the display until i give it another set of digits like 9876?

Thanks in advance

Grumpy_Mike

Quote
If you give it the data to display, does it keep displaying it untill I give it a new 'frame'?
Yes.

PaulRB

Yes.
There are more advantages also. No series resistors needed for the led segments, because the max chip has constant current drivers (one resistor sets that current). Much brighter display since the max chip can source more current than 74hc595. You can drive up to 8 digits with one chip. You can control the brightness over 16 levels from your sketch. The chip can even translate the 0..9 value of each digit you send into the segment patterns automatically.

Moshtaraq

Hi again, my max chips arrived but I think i misunderstood how it worked. I thought if i gave it a 4 bytes of data it would see that as 4 digits or columns in matrixes. I can't find any example scripts without libraries to understand the workings of it. I read somewhere that you give it two bytes, one with the data and one with the command but that's as far as I could go into the workings. Any sources you guys have for me? I like to try things without libraries if possible so i can learn more.

Go Up