1

I am using an Attiny84 with an LM335z temperature sensor to create a temperature sensor. Using the ADC, I obtain the voltage value and perform the necessary conversions to obtain the temperature value. Then, I display this temperature on a 7-segment display. Here is a code snippet where I configure the ADC and the function I use to read the temperature.

void iniPuertos(void) {
    DDRB = 0b00000011; 
    PORTB = 0b00000100; 
    
    DDRA = 0b11111110; 
    
    /
    ADMUX |= (1 << REFS0); 
    ADMUX |= (1 << MUX2) | (1 << MUX0); 
    ADCSRA |= (1 << ADPS0) | (1 << ADPS1) | (1 << ADPS2); 
    ADCSRA |= (1 << ADEN); 

    
    GIMSK |= (1 << INT0);   
    MCUCR |= (1 << 2);  
                
    sei();  

}

int leerTemperatura(void) {
    uint16_t lecturaSensor;
    float voltageSensor = 0.0;
    float temperatura = 0.0;
    int temperaturaSuavizada = 0;
    
    PORTB |= (1 << 0); //Sensor
    _delay_ms(250);

    for (int i = 0; i < 50; i++) {
        ADCSRA |= (1 << ADSC); 
        while (ADCSRA & (1 << ADSC));
            
        lecturaSensor = ADC;
        voltageSensor = lecturaSensor * (5.0 / 1023.0); 
        temperatura = ( voltageSensor / 0.01) - 273.15; 
        temperaturaSuavizada += temperatura;
    }
    temperaturaSuavizada = round(temperaturaSuavizada / 50);
    PORTB &= ~(1 << 0); 
    return temperaturaSuavizada;
}

The issue lies in the variable 'lecturaSensor,' which is responsible for obtaining the ADC reading. This variable seems to erroneously obtain the reading, as when displaying the value on the display, the number shown is incorrect and does not correspond to the temperature. However, if I assign a value like lecturaSensor = 565, the temperature value is displayed correctly. By 'displaying incorrectly,' I mean that not all the LEDs light up as they should. It's worth mentioning that I'm using a BCD decoder. I attempted several changes and modifications to the configuration without success, and I'm unable to identify the error. Additionally, since the Attiny doesn't have UART, I cannot view the value of the variable. I'm seeking assistance in case there's an issue that I'm overlooking.

I'm adding some images: https://imgur.com/a/kzu5jr2

MrNando
  • 11
  • 2
  • What does *not all the LEDs light up* mean? First of all, try to display all values in a loop you expect to be displayed. Show the code where you convert value to BCD for display. Show the code where you update signal for display. If you have no debugWIRE hardware, you can "blink out" values for diagnostics or store them to EEPROM and read with programmer. – dimich Aug 17 '23 at 14:37
  • Welcome to StackOverflow! Please take the [tour] to learn how this site works, and you might want to read "[ask]", too. -- Would you mind to [edit] your question and add some sketches or images of the incorrect display? -- If you think that the value of `lecturaSensor` is the problem, did you try multiple different values? Just one (the 565 you mention) seems not to prove anything. -- Even if you seem to be sure that your display part is correct, please add a [mre]. – the busybee Aug 17 '23 at 14:49
  • Check the LED is working properly before you even use the ADC, or even do any temperature conversions. It's unclear from the post whether it does. Work back from there, next with faked ADC readings that you convert to temperature, and finally using the ADC itself. Another option (when the LED is working) is to display the raw ADC readings without converting to temperature. – Weather Vane Aug 17 '23 at 14:50
  • @MrNando, Recommendation: simplify code. Use `float` math. `voltageSensor = lecturaSensor * (5.0 / 1023.0);` converts the `uint16_t lecturaSensor` to a `double`. Performs a `double` multiplication and then converts the product to a `float`. Suggest `voltageSensor = lecturaSensor * (5.0f / 1023.0f);` instead. Likewise for `temperatura = ( voltageSensor / 0.01) - 273.15;` – chux - Reinstate Monica Aug 17 '23 at 15:00
  • 1
    IDK why you are summing `float` values in `int temperaturaSuavizada` for averaging. This is bound to lead to round-off errors, because `temperaturaSuavizada += temperatura;` is truncating all the fractional parts. – Weather Vane Aug 17 '23 at 15:00
  • 1
    There might be software based serial communication libraries. You have `float temperatura` and `int temperaturaSuavizada` and do `temperaturaSuavizada += temperatura` 50 times. Are you sure no integer overflow can occur? I recommend to use integer or fixed point arithmetic instead of floating point. Adding the unit to the variable names might also help to understand the program. I suggest to [edit] the question and add information about the voltage output of the sensor and the ADC range and resolution to allow us to verify the calculations without searching in the data sheets. – Bodo Aug 17 '23 at 15:05
  • @MrNando, "the number shown is incorrect" --> What number is shown? – chux - Reinstate Monica Aug 17 '23 at 15:07
  • Software UART transmitter for AVR µCs: https://github.com/MarcelMG/AVR8_BitBang_UART_TX – Bodo Aug 17 '23 at 15:31
  • I conducted the test with a loop that displays all the numbers, and it can be seen that it works correctly. Therefore, it's not a fault with the function that converts our numbers to BCD for display. When I try to display the value of the temperature reading, it can be observed that only a part of the display lights up. It seems like it's trying to display the number 2, but it appears truncated. https://imgur.com/a/kzu5jr2 – MrNando Aug 18 '23 at 07:57
  • You shouldn't use double precision floating point on an AVR - it is not a PC. "I need decimal point" is not a valid rationale for introducing floating points in code - all of this could have been written with fixed point. – Lundin Aug 18 '23 at 08:03
  • Anyway, this is not necessarily a software problem. Trouble-shooting ADC involves peeking at the schematic, the voltage ref and so on. So https://electronics.stackexchange.com might be a more suitable site, given that you can also provide the schematic. – Lundin Aug 18 '23 at 08:10

1 Answers1

1

these chips without UARTS are hard to debug all at once. They do have a "DebugWire" port for debugging; if you have access to that and a debugger, you could greatly simplify debugging with the ability to set breakpoitns and read the value of lecturaSensor directly.

If not, here are some steps that I'd go through to debug the system by isolating each part:

  • For the temperature sensor, you could make a program that sets PORTB0 high forever, then measure the analog input from the LM335z to ATtiny with a multimeter. That could help verify the sensor is outputting expected voltages.
  • Looks like ADMUX is configured to use PA0 as the analog reference voltage; what's connected to that pin?
  • Also looks like the ADC clock prescaler is set to divide the CPU clock by 1/128; the datasheet recommends "an input clock frequency between 50 kHz and 200 kHz". Does that value make sense given your CPU frequency?
  • Try sampling the ADC once then returning the lecturaSensor value from this function directly. There could be a bug in the averaging function.
  • "I mean that not all the LEDs light up as they should." - from that, I wonder if the 7-segment display is working as you intend. You could write a program that writes known values to the display to make sure that it and your driver for it are working.

Those are all the ideas I have, good luck debugging!

GandhiGandhi
  • 1,029
  • 6
  • 10
  • "these chips without UARTS are hard to debug all at once" Debugging through UART is stone age stuff (or well, 1990s stuff). You should only use MCUs with single wire debugging interfaces - everything else is sheer masochism. Simply don't pick a MCU which is based on 30 year old technology and all such problems will go away. – Lundin Aug 18 '23 at 08:05