DHT sensor with RGB LED - rgb

I have a DHT11 that outputs temperature and humidity values. I'm trying to Serial.print the colour of the light based on the set temperature conditions. So far I only get 1s and 0s. How can I change these integer values to output string say RED, GREEN or BLUE? Is this possible or do I just need a Serial.print("RED"); in each loop to get it done?
Code
#include <dht.h>
dht DHT;
#define DHT11_PIN A5
int redPin = 10; // Red LED, connected to digital pin 10
int grnPin = 9; // Green LED, connected to digital pin 9
int bluPin = 8; // Blue LED, connected to digital pin 8
void setup(){
Serial.begin(9600);
pinMode(redPin, OUTPUT);// Sets the pins as output for RGB LED
pinMode(grnPin, OUTPUT);
pinMode(bluPin, OUTPUT);
}
void loop() {
int chk = DHT.read11(DHT11_PIN);
int t = DHT.temperature;
int h = DHT.humidity;
Serial.print("Temperature = ");
Serial.print(t);
Serial.print( "," );
Serial.print("Humidity = ");
Serial.print(h);
Serial.print("\n");
delay(60000);
if((DHT.temperature < 26) && (DHT.temperature >= 23.2)) {
// Writing the LED colour pins HIGH or LOW to set colours
digitalWrite(redPin, HIGH); // yellow
digitalWrite(grnPin, HIGH);
delay(100);
digitalWrite(bluPin, LOW);
}
if((DHT.temperature < 23) && (DHT.temperature > 20.2)) {
digitalWrite(grnPin, HIGH); // green
delay(100);
digitalWrite(redPin, LOW);
digitalWrite(bluPin, LOW);
}
if((DHT.temperature < 20) && (DHT.temperature > 17.2)) {
digitalWrite(grnPin, HIGH); // aqua
digitalWrite(bluPin, HIGH);
delay(100);
digitalWrite(redPin, LOW);
}
if(DHT.temperature <= 17) {
digitalWrite(bluPin, HIGH); // blue
delay(100);
digitalWrite(grnPin, LOW);
digitalWrite(redPin, LOW);
}
delay(1000);
// Sensor shouldn't be read too frequently so delay of 1s
}
I will be grateful if I can get some help. Thanks!

Related

I²C Communication from Scratch in C on Raspberry Pi in Linux

I want to create a small library for communication with I²C devices, especially the MPU6050 accelerometer / gyroscope module from scratch in C. Technically, I could use a library like wiringPi, but.. where is the fun with that. Right now I'm trying to write a function which scans all possible 7 bit addresses (0 - 127) and reads the acknowledge bit to find all 'active' addresses of connected I²C devices. To do that, I wrote a small library which can control the GPIO pins by writing to the coresponding GPIO files in /sys/class/gpio. It can for example setup a pin, set its direction (input or output), set its digital output and read a digital input from a pin. I tested all of these functions and they work great and fast.
For communication with the MPU6050 I²C slave I connected the power and ground pins of the MPU board to the Raspberry's GPIO power and ground pins and the SDA and SCL lines to GPIO pins 14 and 15. I read a lot about I²C recently and I do understand how it works. The problem is, that my code to scan through all addresses does not work. Here's my code:
#include <stdio.h>
#include <unistd.h>
#include "string.h"
#include "gpio.h"
#define SCL 14
#define SDA 15
#define FREQ 100000
#define high 1
#define low 0
char binret[8];
void scanI2C();
void charToBin(unsigned char);
void delay();
int main () {
setupPin(SCL, OUTPUT);
setupPin(SDA, OUTPUT);
scanI2C();
}
void scanI2C() {
int addr = 0;
for (int i = 90; i < 128; i++) {
charToBin(i);
// Start Condition
setPin(SDA, high);
setPin(SCL, high);
delay();
setPin(SDA, low);
for (int j = 0; j < 9; j++) {
delay();
setPin(SCL, low);
delay();
setPin(SCL, high);
if (j < 7) {
setPin(SDA, binret[j+1]);
}
// WRITE Bit
if (j == 7) {
setPin(SDA, high);
}
// Listen for ACK bit
if (j == 8) {
setPinDirection(SDA, INPUT);
printf("Checking Address %d (%d%d%d%d%d%d%d%d)", i, binret[0], binret[1], binret[2], binret[3], binret[4], binret[5], binret[6], binret[7]);
if (readPin(SDA) <= 0.5) {
printf(" Bingo!");
}
setPinDirection(SDA, OUTPUT);
printf("\n");
}
}
// Stop Condition
setPin(SCL, low);
delay();
setPin(SDA, high);
delay();
setPin(SCL, high);
delay();
delay();
delay();
delay();
delay();
}
}
void charToBin(unsigned char a) {
memset(binret, 0, sizeof(binret));
int val = 128;
for (int i = 0; i < 8; i++) {
int bit = a & val;
if (bit != 0) {
binret[i] = 1;
}
val /= 2;
}
}
void delay() {
usleep(1000000.0/FREQ);
}
Since I do actually know the address of the MPU6050 I²C slave to be 0x69 or 105 in decimal, I would expect the output to be something like this:
...
Checking Address 103 (01100111)
Checking Address 104 (01101000)
Checking Address 105 (01101001) Bingo!
Checking Address 106 (01101010)
Checking Address 107 (01101011)
Checking Address 108 (01101100)
Checking Address 109 (01101101)
Checking Address 110 (01101110)
...
But no, I don't get a Bingo! at address 105, which means that my I²C communication is definitely not working. Advice on how to address this issue is very much appreciated! Thank you and have a nice day :)
Typically it is the LSB of the 8-bit "address" that is the R/W bit. If you have a device with address 105 I would expect it to respond when your 8-bit address is 210 or 211. Have you tried the entire address space?
Does readPin() return a float? If not, why are you comparing to a float?
It looks like you are changing SDA while SCL is high and you are sending the address bits. I don't think that is allowed.
Do you have a pullup resistor on SDA?
Have you verified signal levels and timing with an oscilloscope?

Write rate of DAC MCP4725

I have a buffer which contains 16000 PCM samples of 8Khz 8-bit mono. I am trying to play it using 12 bit MCP4725 DAC. I have tried using micros() to control the write interval for the DAC. Here's my code -
uint8_t soundData[16000] = { 234,206,79,255,249,....,210,222 }; // 8Khz 8-bit mono
void setup() {
Serial.begin(115200);
Wire.begin(D2, D1);
delay(100); // delay 100 ms
Serial.flush();
delay(1000);
}
void value_write(uint16_t temp){
Wire.beginTransmission(0x62);
Wire.write(64);
Wire.write(temp >> 4); // the 8 most significant bits...
Wire.write((temp & 15) << 4); // the 4 least significant bits...
Wire.endTransmission();
}
void loop() {
unsigned long currentMicros = micros();
// 125 uS sampling for 8KHz signal
if(currentMicros - previousMicros > 125) {
Serial.print("Index: ");
Serial.println(indx);
uint16_t temp = map(soundData[indx++], 0, 255, 0, 4095);
value_write(temp);
}
}
The write should logically be completed within 2 seconds but takes way more time. Any help regarding successfully writing the PCM values to the DAC at 8000Hz is greatly appreciated.

Seven-segment display using 595

I am having some trouble coding my seven-segment display using a shift register and push button. The aim is for the display to count up when the button is pressed. 0-9 then; A, B, C, D, E, and F. I did manage to get this working at first but the task was changed so the "shiftOut" command was not allowed to be used.
With my adjusted code my seven-segment display doesn't seem to be working at all now. I have tried to do a lot of my own troubleshooting (i.e. looking into debouncing, arrays, and bit-banging). Any help would be appreciated. Thanks. PS: this is my first question so sorry if the format is wrong.
/* Pins to connect to common-cathode LED display via a 74HC595:
DP-7, A-6, B-5, C-4, D-3, E-2, F-1, G-15
*/
const byte ledCharSet[128] = {
// 00-0F: Hex digits
B10000001, B11001111, B10010010, B10000110, // 0123
B11001100, B10100100, B10100000, B10001111, // 4567
B10000000, B10000100, // 89
B10001000, B11100000, B10110001, B11000010, // AbCd
B10110000, B10111000, // EF
};
//// Pin connected to latch pin (ST_CP) of 74HC595
const int latchPin = 8;
//// Pin connected to clock pin (SH_CP) of 74HC595
const int clockPin = 12;
//// Pin connected to Data in (DS) of 74HC595
const int dataPin = 11;
//// Pin connected to display's common annode
const int faderPin = 10;
int _B = 7;
bool b;
int count=0;
int value;
long time = 0;
long debounce = 500;
void setup() {
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(_B, INPUT_PULLUP);
b = true;
toggleLatch();
toggleCLK();
Serial.begin(9600);
}
void toggleLatch() {
digitalWrite(latchPin, HIGH); digitalWrite(latchPin, OUTPUT);
}
void toggleCLK() {
digitalWrite(clockPin, HIGH); digitalWrite(clockPin, LOW);
}
void loop() {
unsigned char count; // debounce counter
if (b != digitalRead(_B)) {
for(count = 0; count<20 && b != digitalRead(_B); count++);
//register the change if we have confirmed it 20 consecutive times
b=((count>=20 && b!=digitalRead(_B))?!b:b);
if(!b) {
count--;
} // button is pushed
}
toggleLatch();
void shiftBit(bool dataPin) { digitalWrite(ledCharSet,dataPin); toggleCLK(); }
void shiftByteMSF(unsigned char b) {
unsigned char b = ledCharSet[count];
unsigned char m; // use m to select the bits in b one at a time
m = 1;
for (m = B10000000; m>0; m <<= 1) {
if (b & m) {
digitalWrite(dataPin, HIGH);
} else {
digitalWrite(dataPin, LOW);
}
}
toggleLatch();
}
if (count==16) {
count=0; //reset
}
}
This is the first code I used, which worked fine.
/* Pins to connect to common-cathode LED display via a 74HC595:
DP-7, A-6, B-5, C-4, D-3, E-2, F-1, G-15 (shiftOut using MSBFIRST)
*/
const byte ledCharSet[128] = {
// 00-0F: Hex digits
B10000001, B11001111, B10010010, B10000110, // 0123
B11001100, B10100100, B10100000, B10001111, // 4567
B10000000, B10000100, // 89
B10001000, B11100000, B10110001, B11000010, // AbCd
B10110000, B10111000, // EF
};
//// Pin connected to latch pin (ST_CP) of 74HC595
const int latchPin = 8;
//// Pin connected to clock pin (SH_CP) of 74HC595
const int clockPin = 12;
//// Pin connected to Data in (DS) of 74HC595
const int dataPin = 11;
//// Pin connected to display's common annode
const int faderPin = 10;
int _B = 7;
int reading;
int previous = LOW;
int counter=0;
long time = 0;
long debounce = 500;
void setup() {
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(_B, INPUT_PULLUP);
Serial.begin(9600);
}
void loop() {
reading = digitalRead(_B);
Serial.print(counter);
if (reading == HIGH && previous == LOW && millis() - time > debounce) {
counter++;
time = millis();
}
previous = reading;
byte bitsToSend = ledCharSet[counter];
bitsToSend = bitsToSend ^ B11111111;
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, bitsToSend);
digitalWrite(latchPin, HIGH);
digitalWrite(11, 255);
digitalWrite(11, 0);
if (counter==16) {
counter=0; //reset count
}
}

PING sensor on RPI, start counting when less than 40cm?

I have a PING sensor (HC-SR04) hooked up to my RPI. I want it to start counting when the sensor sees less than 40 cm. It should stop counting again when the sensor again sees less than 40 cm, print out the time and start counting again.
How can I do this?
This is my code:
#include <stdio.h>
#include <stdlib.h>
#include <wiringPi.h>
#define TRUE 1
#define TRIG 5
#define ECHO 6
void setup() {
wiringPiSetup();
pinMode(TRIG, OUTPUT);
pinMode(ECHO, INPUT);
//TRIG pin must start LOW
digitalWrite(TRIG, LOW);
delay(30);
}
int getCM() {
//Send trig pulse
digitalWrite(TRIG, HIGH);
delayMicroseconds(20);
digitalWrite(TRIG, LOW);
//Wait for echo start
while(digitalRead(ECHO) == LOW);
//Wait for echo end
long startTime = micros();
while(digitalRead(ECHO) == HIGH);
long travelTime = micros() - startTime;
//Get distance in cm
int distance = travelTime / 58;
return distance;
}
int i;
int main(void) {
setup();
while (1)
{
printf("Distance: %dcm\n", getCM());
delay(250);
}
return 0;
}
The code doesn't measure the distance. It only measures the duration of the reflected signal. To get the distance you need to measure the delay between the beginning of ping, and the beginning of echo:
startTime = micros();
digitalWrite(TRIG, HIGH);
delayMicroseconds(20);
digitalWrite(TRIG, LOW);
//Wait for echo start
while(digitalRead(ECHO) == LOW);
long travelTime = micros() - startTime;
Of course, this is just a skeleton: you need to debounce the echo to guard yourself against background noises and other glitches.

Why doesn't the LED turn off?

I have a program (copied below) that has an alarm that starts in 10 seconds, which starts a LED that blinks every two seconds. I would like to push a button that turns off the alarm / LED. The LED blinks as intended but does not turn off when I push the button. Any idea why? Code below:
#include <Time.h>
#include <TimeAlarms.h>
#define buttonPin 2 // assigns pin 2 as buttonPin
#define ledPin 13 // assigns pin 13 as ledPin
int buttonState; // variable for reading the pushbutton status
int lastButtonState = LOW;
unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
unsigned long debounceDelay = 50; // the debounce time; increase if the output flickers
void setup() {
Serial.begin(9600); // start Serial Monitor
setTime(0, 0, 0, 1, 1, 2018); // set time to 00:00:00 Jan 1 2018
Alarm.alarmRepeat(0, 0, 10, DailyAlarm); // Alarm triggered in 10 sec
pinMode(ledPin, OUTPUT); // assigns ledPin as led output pin.
pinMode(buttonPin, INPUT); // assigns buttonPin as input pin
// digitalWrite(ledPin, ledState); // LED is off initially
}
void loop() {
digitalClockDisplay();
Alarm.delay(1000); // wait one second between clock display
int reading = digitalRead(buttonPin);
if (reading != lastButtonState) {
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
if (reading != buttonState) {
buttonState = HIGH;
Serial.print(buttonState);
}
}
}
void DailyAlarm() {
Serial.println("Alarm");
while (buttonState == LOW) {
blink(2000); // blink every 2s
}
}
void blink(int period) {
digitalWrite(ledPin, HIGH);
delay(period / 2);
digitalWrite(ledPin, LOW);
delay(period / 2);
}
void digitalClockDisplay() {
// digital clock display of the time
Serial.print(hour());
printDigits(minute());
printDigits(second());
Serial.println();
}
void printDigits(int digits) {
Serial.print(":");
if (digits < 10)
Serial.print('0');
Serial.print(digits);
}
int buttonState; // variable for reading the pushbutton status
You haven't initialized the button state
Try
boolean buttonState = LOW
And Don't mix integers and booleans
use this
boolean lastButtonState = LOW;
instead of
int lastButtonState = LOW;

Resources