1

I'm new to the arduino board and my teacher gave us a project with little to no teaching about the language the board uses, or how to effectively program with it. I'm trying to read temperature from a DHT11 and display it on two separate 7-segments displays. I've been trying to do this by editing a code he provided us that makes one display count from 0 to 9. I've been to hook up and read the DHT11 and split the temperature into two variables. But I have no idea how to make the variables display on the seven segment displays. My code is.

//DHT11 set up
#include <dht11.h>
dht11 DHT11;
void setup()
{
   DHT11.attach(4);
   for (int i = 0; i < 4; ++i)
    pinMode(i, OUTPUT);
   for (int i = 8; i < 11; ++i)
    pinMode(i, OUTPUT);
}
static int temp = DHT11.fahrenheit();
static int digit_0 = temp % 10;
static int digit_1 = temp - digit_0;
static int digit_2 = digit_1 / 10;
// Output pins.
static int output[] = {0,1,2,3};
// 8421 code lookup table.
static int segs_encoding[][4] =
  {{0,0,0,0},   //=0
    {0,0,0,1},  //=1
    {0,0,1,0},  //=2
    {0,0,1,1},  //=3
    {0,1,0,0},  //=4
    {0,1,0,1},  //=5
    {0,1,1,0},  //=6
    {0,1,1,1},  //=7
    {1,0,0,0},  //=8
    {1,0,0,1}}; //=9
// Outputs an 8421 decimal digit on the output pins from
// base to base + 3 in big endian order.
void show(int base, int num) {
 for (int i = 0; i < 4; ++i) {
   if(segs_encoding[num][i] == 1) {
     digitalWrite(base + 3 - i , HIGH);
   } else {
     digitalWrite(base + 3 - i , LOW);
   }
  }
}
// Output a 2 digit decimal value.
void show_2digit_decimal(int num) {
// force value to displayable range because show() doesn't do any sanity 
  if (num < 0)
    num = 0;
  if (num > 99)
    num = 99;
  // display it.
  show(0, num%10);
  show(8, num/10);
} 
void loop() { 
  static int i = 0;
  show_decimal(i);
  delay(1000);
// Increases the counter.
  ++i;
  if (i == 10)
    i = 0; 
}   

Let me know if you guys need pictures of my breadboard set up, thanks for any help you guys can provide.

  • You need to at the very least tell us which IO pins the second digit of the display is on. The language the board uses is basically standard c with a few additions for controlling the IO pins. – Andrew Oct 20 '16 at 11:34
  • I'm assuming you mean the pins on the arduino board? The second one is connected to pins 8, 9, 10, 11. – user27542 Oct 20 '16 at 11:38
2

The show() function already has support for specifying the first pin of the display. So if the second digit is starting at pin 8 and connected in the same order then it should be as simple as:

// Output a 2 digit decimal value.
void show_2digit_decimal(int num) {
  // force value to displayable range because show() doesn't do any sanity checks
  if (num < 0)
    num = 0;
  if (num > 99)
    num = 99;
  // display it.
  show(0, num%10);
  show(8, num/10); // int/int always rounds down to the nearest int
}

You will also have to add the appropriate pinMode(<pin>, OUTPUT); commands to the setup() function to make the pins outputs.

----- update

To get the temperature to display first get rid of these lines, they aren't doing anything useful

static int temp = DHT11.fahrenheit();
static int digit_0 = temp % 10;
static int digit_1 = temp - digit_0;
static int digit_2 = digit_1 / 10;

And then change the loop function to being

void loop() { 
  show_2digit_decimal(DHT11.fahrenheit());
  delay(500);
}

Although unless the teacher is completely incompetent you should have been able to work that out yourself, it's not exactly rocket science. If unsure take a guess and try it first before asking. The logic is simple enough that you should be able to work it out. For syntax errors the compiler error messages will normally tell you exactly what's wrong.

  • I added that to my code, but I'm getting a compiling error. My new code looks like – user27542 Oct 20 '16 at 12:07
  • I edited my new code into the question. – user27542 Oct 20 '16 at 12:10
  • 1) What error are you getting. "a compiler error" is totally useless. 2) what happened to the rest of the code? Your loop() function has vanished. What is the program supposed to do after it's done the setup? Arduino has a hidden top level which in c would be written as main(){setup();while(1) loop();}. You need a loop() function if you want anything to happen. – Andrew Oct 20 '16 at 13:05
  • I brought back the loop function and that fixed the error. I'm trying to get the first digit of the temperature to display on 7 segment display and the second digit to display on the second 7 segment display. I know that the code in the loop function wont do that, I just have no idea what to change it too to make it do that. – user27542 Oct 20 '16 at 13:14
  • See the update in the answer – Andrew Oct 20 '16 at 13:33
2

There are many issues with this code:

  • The compiler says “error: ‘show_decimal’ was not declared in this scope”. Indeed, you named the function show_2digit_decimal(), so you should call it by that name.
  • The compiler also said: “warning: ‘output’ defined but not used”. There is no valid reason to leave something defined that you do not use. Just remove it.
  • You also have a function named sertup() that you defined but never used. It looks like a typo. You should remove the function, and put it's current contents inside setup().
  • You have the variables digit_0, digit_1 and digit_2 that serve no useful purpose. Remove them as well.
  • You wrote, at top level: static int temp = DHT11.fahrenheit(); Don't do this. This kind of initialization happens before setup(), i.e. before you had a chance to attach() the sensor to its pins.
  • Your array segs_encoding is not a 7-segment encoding, it's just the binary encoding of the numbers. You don't need it: the processor already knows how to count in binary, and you can replace segs_encoding[num][i] by num>>i&1. If you really have 7-segment displays, you need 7 pins for each, unless you multiplex them. Search this site for “7 segment” to see how to drive them.
  • The section if(segs_encoding[num][i] == 1) { digitalWrite(base + 3 - i , HIGH); ... can be simplified to digitalWrite(base + 3 - i , segs_encoding[num][i]); or, considering the previous point, to digitalWrite(base + 3 - i , num >> i & 1);
  • The test if (num < 0) num = 0; if (num > 99) num = 99; can be written more succinctly by using the function Arduino provides for that: num = constrain(num, 0, 99);
  • In loop(), you are only displaying a counter. You probably should display the temperature instead.

All the previous comments lead to the following version of the code:

#include <dht11.h>

const int units_base_pin = 0;  // units on pins 0..3
const int tens_base_pin = 8;   // tens on pins 8..11

dht11 DHT11;

// Outputs a number in binary on the output pins from
// base to base + 3 in big endian order.
void show(int base, int num) {
    for (int i = 0; i < 4; ++i) {
        digitalWrite(base + 3 - i , num >> i & 1);
    }
}

// Output a 2 digit decimal value.
void show_2digit_decimal(int num) {
    // force value to displayable range because show() doesn't do any sanity
    num = constrain(num, 0, 99);
    // display it.
    show(units_base_pin, num%10);
    show(tens_base_pin, num/10);
}

void setup() {
    DHT11.attach(4);
    for (int i = 0; i < 4; ++i)
        pinMode(i, OUTPUT);
}

void loop() {
    show_2digit_decimal(DHT11.fahrenheit());
    delay(1000);
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.