สวัสดีครับพอดีผมหัดใช้ Arduino ไม่นานเท่าไร แล้วลองหัดเขียนการแสดงผลอุณหภูมิ DS18B20 แสดงผลด้วย 7 Segment โดยใช้ไอซีชิปรีจิสเตอร์ 74HC595ในการเลื่อนบิต สามารถแสดงอุณหภุมิได้ตามเป้าหมายครับ แต่ติดตรงการแสดงผลครับมันแสดงผลแบบกระพริบๆ ซึ่งปกติมันจะกระพริบจนตาเราไม่สามารถเห็น แต่นี่ยังเห็นว่ากระพริบครับ ตาม Source Code ด้านล่างครับ ผมขอคำแนะนำด้วยครับ ขอบคุณครับ
#include <OneWire.h>
int DS18S20_Pin = 2; //DS18S20 Signal pin on digital 2
OneWire ds(DS18S20_Pin); // on digital pin 2
const int digitPins[4] = {8,9,10,11}; //4 common anode pins of the display
const int latchPin = 5; //74HC595 Pin 12
const int dataPin = 6; //74HC595 Pin 14
const int clockPin = 7; //74HC595 Pin 11
const byte digit[10] = //seven segment digits in bits
{
B00111111, //0
B00000110, //1
B01011011, //2
B01001111, //3
B01100110, //4
B01101101, //5
B01111101, //6
B00000111, //7
B01111111, //8
B01101111 //9
};
int digitBuffer[4] = {0};
int digitScan = 0, flag=0, soft_scaler = 0;
float tempC;
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 = ds.read();
}
ds.reset_search();
byte MSB = data[1];
byte LSB = data[0];
float tempRead = ((MSB << | LSB); //using two's compliment
float TemperatureSum = tempRead / 16;
return TemperatureSum;
}
void setup()
{
//Serial.begin(9600);
for(int i=0;i<4;i++)
{
pinMode(digitPins,OUTPUT);
}
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
}
//writes the temperature on display
void updateDisp()
{
for(byte j=0; j<4; j++)
digitalWrite(digitPins[j], LOW);
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, B11111111);
digitalWrite(latchPin, HIGH);
//delay(1);
delayMicroseconds(1);
digitalWrite(digitPins[digitScan], HIGH);
digitalWrite(latchPin, LOW);
if(digitScan==2)
shiftOut(dataPin, clockPin, MSBFIRST, ~(digit[digitBuffer[digitScan]] | B10000000)); //print the decimal point on the 3rd digit
else
shiftOut(dataPin, clockPin, MSBFIRST, ~digit[digitBuffer[digitScan]]);
digitalWrite(latchPin, HIGH);
digitScan++;
if(digitScan>3) digitScan=0;
}
void loop()
{
float temperature = getTemp();
// Serial.println(temperature);
//tempF = ((tempK - 2.5) * 9 / 5) - 459.67;
//Celsius temperature display
tempC = int(temperature*100);
digitBuffer[3] = int(tempC)/1000;
digitBuffer[2] = (int(tempC)%1000)/100;
digitBuffer[1] = (int(tempC)%100)/10;
digitBuffer[0] = (int(tempC)%100)%10;
updateDisp();
//delay(1);
//delayMicroseconds(1);
}
#include <OneWire.h>
int DS18S20_Pin = 2; //DS18S20 Signal pin on digital 2
OneWire ds(DS18S20_Pin); // on digital pin 2
const int digitPins[4] = {8,9,10,11}; //4 common anode pins of the display
const int latchPin = 5; //74HC595 Pin 12
const int dataPin = 6; //74HC595 Pin 14
const int clockPin = 7; //74HC595 Pin 11
const byte digit[10] = //seven segment digits in bits
{
B00111111, //0
B00000110, //1
B01011011, //2
B01001111, //3
B01100110, //4
B01101101, //5
B01111101, //6
B00000111, //7
B01111111, //8
B01101111 //9
};
int digitBuffer[4] = {0};
int digitScan = 0, flag=0, soft_scaler = 0;
float tempC;
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 = ds.read();
}
ds.reset_search();
byte MSB = data[1];
byte LSB = data[0];
float tempRead = ((MSB << | LSB); //using two's compliment
float TemperatureSum = tempRead / 16;
return TemperatureSum;
}
void setup()
{
//Serial.begin(9600);
for(int i=0;i<4;i++)
{
pinMode(digitPins,OUTPUT);
}
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
}
//writes the temperature on display
void updateDisp()
{
for(byte j=0; j<4; j++)
digitalWrite(digitPins[j], LOW);
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, B11111111);
digitalWrite(latchPin, HIGH);
//delay(1);
delayMicroseconds(1);
digitalWrite(digitPins[digitScan], HIGH);
digitalWrite(latchPin, LOW);
if(digitScan==2)
shiftOut(dataPin, clockPin, MSBFIRST, ~(digit[digitBuffer[digitScan]] | B10000000)); //print the decimal point on the 3rd digit
else
shiftOut(dataPin, clockPin, MSBFIRST, ~digit[digitBuffer[digitScan]]);
digitalWrite(latchPin, HIGH);
digitScan++;
if(digitScan>3) digitScan=0;
}
void loop()
{
float temperature = getTemp();
// Serial.println(temperature);
//tempF = ((tempK - 2.5) * 9 / 5) - 459.67;
//Celsius temperature display
tempC = int(temperature*100);
digitBuffer[3] = int(tempC)/1000;
digitBuffer[2] = (int(tempC)%1000)/100;
digitBuffer[1] = (int(tempC)%100)/10;
digitBuffer[0] = (int(tempC)%100)%10;
updateDisp();
//delay(1);
//delayMicroseconds(1);
}