Need help on my first simple project [TMP36]

Hello, I'm new to programming with Arduino. I started just today.
I was trying to create a simple circuit that has following items;

  • Arduino UNO board
  • red LED
  • yellow LED
  • blue LED
  • a TMP36 sensor

My objective is to glow the blue LED if temperature is below 20 degrees of celsius, the yellow if the temperature is below 30 but above 20 degrees of celsius and red if temperature is above 30 degrees of celsius.

The code compiled okay and didn't rise any syntax errors but I'm experiencing a bug as when it is run it does nothing.
I need help with this.

Here's the code:

// C++ code
//


// Class Led
class Led {
private:
  int pin;  // Pin number

public:
  // Class constructor
  Led(int x) {
    // Set pin number upon creating instance.
    pin = x;
    // Set pin mode.
    pinMode(pin, OUTPUT);
  }

  // Method to get pin number.
  int getPin() {
    return pin;
  }
  // Method to glow the bulb.
  void glow() {
    digitalWrite(pin, HIGH);
  }
  // Method to turn off the bulb.
  void off() {
    digitalWrite(pin, LOW);
  }
};


// Pin which the TMP36 sensor is connected to.
const int temperaturePin = A0;
// Variable which stores the temperature.
float temperature; // This is global.

// Function to get temperature. // Each time this function is called updates the 'temperature' variable
void senseTemperature(){
  // Read the analog signal (voltage) from the TMP36 sensor.
  int sensorValue = analogRead(temperaturePin);
  float voltage = sensorValue * (5.0 /1023.0);
  // Set temperature.
  temperature = (voltage - 0.5) * 100.0;
}

// Create instances of LEDs. Declare and initialize them.
Led red(11);
Led yellow(10);
Led blue(9);



// All the global declarations are done here goes the code.

void setup() {
  // There's nothing to do here, yet.
  // Create instances of LEDs. Declare and initialize them.
  red = Led(11);
  yellow = Led(10);
  blue = Led(9);
}

void loop() {
  blue.off();
  yellow.off();
  red.off();
  senseTemperature();
  if (temperature < 20.0) {
    blue.glow();
  } else if (temperature < 30.0) {
    yellow.glow();
  } else {
    red.glow();
  }
  delay(1000); // Delay the loop by 1 second before checking the sensor again.
}

Any guidance will be highly appreciated.

I'm also new to asking questions via forums and if you need more information please let me know.

I'm just replying to watch this Marius as I've not seen a newbie use OOP for their first program!
So I'm hoping to learn about OOP myself.

1 Like

Apart from any other problems, you are turning the LEDs off each time through loop() so don't expect to see much from them

    red = Led(11);
    yellow = Led(10);
    blue = Led(9);

You have already created instances of the Led class so why do this ? Even if it worked these instances would be local to setup()

It is common to create the instances of a class as global then to set the characteristics of each instance in setup() but that is not what you are doing because the constructor takes the pin number as a parameter

If you don't have previous object programming experience and start with classes , you may encounter difficulties.
Just to start, you defined the three Led class instance and implicitly called the constructors here:

// Create instances of LEDs. Declare and initialize them.
Led red(11);
Led yellow(10);
Led blue(9);

This means you don't need to do anything more, especially this:

  // Create instances of LEDs. Declare and initialize them.
  red = Led(11);
  yellow = Led(10);
  blue = Led(9);

The constructor doesn't return anything so I think with those statements you completely voided the three instances. Just remove those lines.

The second (small) problem is when reading the temperature you turn off al the leds while you should instead glow the one corresponding to the value read, and dim the others:

void loop() {
  senseTemperature();
  if (temperature < 20.0) {
    blue.glow();
    yellow.off();
    red.off();
  } else if (temperature < 30.0) {
    blue.off();
    yellow.glow();
    red.off();
  } else {
    blue.off();
    yellow.off();
    red.glow();
  }
  delay(1000); // Delay the loop by 1 second before checking the sensor again.
}

Just a few side notes.

  1. by convention constans are indicated in full capital letters
  2. it is better to put the pin definitions as constant symbols, to avoid having to look for all the points in the code where you use them in case of changes
  3. if you group all configuration values as the first code lines, you'll make changes easier

Example:

// *** CONFIGURATION
// Pin which the TMP36 sensor is connected to.
const byte P_TEMP = A0;
const byte P_BLUE = 9;
const byte P_YELLOW = 10;
const byte P_RED = 11;

// *** GLOBALS
// Variable which stores the temperature.
float temperature;
1 Like

I'm familiar with OO coding in other languages, but my C++ knowledge of OO syntax is a little patchy. When I saw those lines, I also immediately thought they are not needed/wanted. I guess @marius_charith may be feeling the same because they copied & pasted the same comment in 2 places.

Doesn't the constructor return a new object, or a pointer/reference? Usually the keyword new is used, but not here. So what exactly will these code lines do? I guess you are correct to say they are doing something that prevents the code from working as desired.

I think the constructor is called back, so the previous instance will be voided (or overwritten on the same address).

Anyway, I just made a test on Wokwi, and even the original the code (I mean the one with the setup duplicated constructors) works fine, it just needs changing the loop with the one I posted before to correctly turn leds on and off. So, even with that useless duplicated contructors, it can do its job. ;-)

1 Like

I must be missing something obvious there, I don't see what was wrong with @marius_charith 's original code in loop(). Yes, it switches all 3 LEDs off, but then it immediately switches/glows one of them.

You will see that many libraries have a begin method. This is because there is hardware setup for the processor to be done and constructors run before this. You may want to do the same.

I'd suggest that you start with something that avoids your own classes. Add OO stuff in small increments once you have a simpler program working.

Hello marius_charith

Consider this "classless" OOP example:

//https://forum.arduino.cc/t/need-help-on-my-first-simple-project-tmp36/1240947
//https://europe1.discourse-cdn.com/arduino/original/4X/7/e/0/7e0ee1e51f1df32e30893550c85f0dd33244fb0e.jpeg
#define ProjectName "Need help on my first simple project [TMP36]"
#define NotesOnRelease "Arduino MEGA tested"
// make names
enum LedNames {Red, Green, Blue};
enum MinMax {Min, Max};
// make variables
constexpr uint8_t LedPins[] {9, 10, 11};
constexpr uint8_t PotPin {A8};
constexpr int16_t TempRange [] {0, 100};
// make structures
struct TEMP2LED
{
  uint8_t pin;
  uint16_t temp[2];
  void make()
  {
    pinMode (pin, OUTPUT);
  }
  void run(uint16_t temSensor)
  {
    digitalWrite(pin, (temSensor >= temp[Min] and temSensor < temp[Max]));
  }
} temp2leds[]
{
  // configure the system here:
  // LedPin, temp-min, temp-max
  {LedPins[Blue], TempRange[Min], 22},
  {LedPins[Green], 23, 33},
  {LedPins[Red], 33, TempRange[Max]},
};
// make support
void heartBeat(const uint8_t LedPin, uint32_t currentMillis)
{
  static bool setUp = false;
  if (setUp == false) pinMode (LedPin, OUTPUT), setUp = true;
  digitalWrite(LedPin, (currentMillis / 500) % 2);
}
// make application
void setup()
{
  Serial.begin(115200);
  Serial.print("Source: "), Serial.println(__FILE__);
  Serial.print(ProjectName), Serial.print(" - "), Serial.println(NotesOnRelease);
  for (auto &temp2led : temp2leds) temp2led.make();
  Serial.println(" =-> and off we go\n");
}
void loop()
{
  uint32_t currentMillis = millis();
  heartBeat(LED_BUILTIN, currentMillis);
  for (auto &temp2led : temp2leds) temp2led.run(map(analogRead(PotPin), 0, 1023, TempRange[Min], TempRange[Max]));
}

Have a nice day and enjoy coding in C++.

1 Like

Thanks a lot. I made the changes it works.

About my previous code, it was alright. I found out I have connected te LED s in a wrong way.

Hello Delta_G

You're right and that's why I used inverted commas.

Anyway, a real "classless" and simpler code can be like:

// *** CONFIGURATION
const byte P_TEMP = A0;
const byte P_BLUE = 9;
const byte P_YELLOW = 10;
const byte P_RED = 11;

// *** GLOBALS
float Temp;

void setup() {
  pinMode(P_BLUE, OUTPUT);
  pinMode(P_YELLOW, OUTPUT);
  pinMode(P_RED, OUTPUT);
}

void loop() {
  senseTemperature();
  digitalWrite(P_BLUE, (Temp < 20.0);
  digitalWrite(P_YELLOW, (Temp >= 20.0 && Temp < 30.0);
  digitalWrite(P_RED, (Temp >= 30.0);
  delay(1000); // Delay the loop by 1 second before checking the sensor again.
}

// Function to get temperature. // Each time this function is called updates the 'Temp' variable
void senseTemperature(){
  // Read the analog signal (voltage) from the TMP36 sensor.
  int sensorValue = analogRead(P_TEMP);
  float voltage = sensorValue * (5.0 /1023.0);
  // Set temperature.
  Temp = (voltage - 0.5) * 100.0;
}
3 Likes

Thanks a lot this was really helpful and a lot of new knowledge.

Hey @paulpaulson thank you for your help. This was a lot of new syntax for me, so I don't think I understood it 100% but I will save your code and learn from it in future.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.