You need to log in to create posts and topics.

The HCSR04 doesn't work with the attiny2313. Rev. 2051

"I'm trying to use the HCSR04 but I can't get it to work. I tried it this way,

and also this other way. But when I upload the program physically to my attiny2313, it works fine. I set up my terminal like this: picocom -b 4800 --parity n --data 8 --stop 1 --echo /dev/ttyUSB0.

This is my code:

#define F_CPU 1000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "UART_LIB.h"

#define NUM_MUESTRAS 5
#define TIMEOUT_MS 60
#define TIMEOUT_TICKS (F_CPU/1000*TIMEOUT_MS/8) // Para prescaler 8

// Variables globales
volatile uint16_t tiempo_echo = 0;
volatile uint8_t flag_captura = 0;


// Interrupción de CAPTURA
ISR(TIMER1_CAPT_vect) {
    cli(); //deshabilitar interrupciones
    if (TCCR1B & (1 << ICES1)) { // Flanco de SUBIDA
        TCNT1 = 0;
        TCCR1B &= ~(1 << ICES1);
    } else { // Flanco de BAJADA
        tiempo_echo = ICR1;
        flag_captura = 1;
        TCCR1B |= (1 << ICES1);
    }
    sei(); // Habilitar interrupciones
}

void initInputCapture() {
    DDRD &= ~(1 << PD6); // PD6 como entrada
    
    // Configuracion timer
    TCCR1A = 0;
    TCCR1B = (1 << ICES1)|(1 << CS11); // Flanco de subida inicial
    TIMSK = (1 << ICIE1); // Habilitar interrupción de captura
    sei();
}

void triggerHC_SR04() {
    DDRB |= (1 << DDB7); // DDB7 como salida (Trig)
    PORTB |= (1 << PB7);
    _delay_us(10);
    PORTB &= ~(1 << PB7);
    _delay_us(2);
    }
    

int main() {
    UART_Init(4800);
    initInputCapture();

    float suma_total_distancias = 0;
    uint8_t cuenta_muestras_validas = 0;

    while (1) {
        triggerHC_SR04();
        flag_captura = 0; // Reiniciar flag
        TCNT1 = 0; // Reiniciar Timer1
        
        // Espera con timeout 
        uint32_t timeout = 0;
        while (!flag_captura && timeout++ < TIMEOUT_TICKS);

        if (flag_captura) {
            float distancia_m = (float)tiempo_echo * 8 / 58;

            // Filtro de rango (2cm - 400cm)
            if (distancia_m >= 2 && distancia_m <= 400) {
                suma_total_distancias += distancia_m;
                cuenta_muestras_validas++;

                if (cuenta_muestras_validas == NUM_MUESTRAS) {
                    float promedio = suma_total_distancias / NUM_MUESTRAS;
                    
                    // Enviar a UART
                    UART_Transmit_Text("Distancia: ");
                    UART_Transmit_Number((uint16_t)promedio);
                    UART_Transmit_Text(" m\r\n");
                    
                    suma_total_distancias = 0;
                    cuenta_muestras_validas = 0;
                }
            }else {
                UART_Transmit_Text("Medicion fuera de rango\r\n");
            }
        } else {
            UART_Transmit_Text("Timeout - Sin eco\r\n");
        }

        _delay_ms(200); // Retardo adicional
    }
}

 

#include "UART_LIB.h"

//static char _uart_buffer_[50];

void UART_Init(uint16_t baudrate){
	
		uint16_t regUBRR = F_CPU/(baudrate*16UL) - 1;
		
		// Cargamos los valores de BAUDRATE en los registros UBRR;
		UBRRH = (uint8_t) (regUBRR>>8);
		UBRRL = (uint8_t) (regUBRR);
		
		//Configuramos modo de operacion de 8 bits de datos;
		//UCSRB &= ~(1<<UCSZ2);
		UCSRC =  (1<<UCSZ1)|(1<<UCSZ0);
		
		//Sin paridad;
		UCSRC &= ~( (1<<UPM1)|(1<<UPM0) );
		
		//Modo asincrono;
		UCSRC &= ~(1<<UMSEL);
		
		//Habilitamos los pines Tx Rx;
		UCSRB = ( (1<<RXEN)|(1<<TXEN) );
		
		
}

void UART_Transmit_char(uint8_t data){
	// Espera a que el registro de transmisión esté vacío
	while (!(UCSRA & (1 << UDRE)));
	// Carga el dato en el registro de transmisión
	UDR = data;
}


void UART_Transmit_Text(char *texto){
	while(*texto){
		UART_Transmit_char(*texto);
		texto++;
	}
}


/*void UART_Transmit_Printf(char *str, ...){
	
	va_list args;
	va_start(args,str);
	vsnprintf(_uart_buffer_, 50, str, args);
	va_end(args);
	UART_Transmit_Text(_uart_buffer_);
	
}*/

void UART_Transmit_Number(uint16_t number) {
    if (number == 0) {
        UART_Transmit_char('0');
        return;
    }

    char buffer[6]; // Buffer para almacenar dígitos (máximo 3 dígitos para uint8_t)
    uint8_t index = 0;

    while (number > 0) {
        buffer[index++] = (number % 10) + '0'; // Convierte el dígito a carácter ASCII
        number /= 10;
    }

    // Envía los dígitos en orden inverso
    for (int i = index - 1; i >= 0; i--) {
        UART_Transmit_char(buffer[i]);
    }
}

    // Nueva función para transmitir números flotantes
/*void UART_Transmit_Float(float number) {
    uint16_t integer = (uint16_t)number;
    uint16_t decimal = (uint16_t)((number - integer) * 100);
    
    UART_Transmit_Number(integer);
    UART_Transmit_char('.');
    if(decimal < 10) UART_Transmit_char('0');
    UART_Transmit_Number(decimal);
}*/


bool UART_DataAvailable(void){
	return ( UCSRA &(1<<RXC) );
}

uint8_t UART_Receive(void) {
	while (!(UCSRA & (1<<RXC))); // Espera hasta que se reciba un byte completo
	return UDR; // Retorna el byte recibido
}

 

#ifndef UART_LIB_H_
#define UART_LIB_H_

#define F_CPU 1000000UL
#include <avr/io.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdbool.h>

void UART_Init(uint16_t baudrate);
void UART_Transmit_char(uint8_t data);
void UART_Transmit_Text(char *texto);
//void UART_Transmit_Printf(char *str, ...);
void UART_Transmit_Number(uint16_t number);
//void UART_Transmit_Float(float number);
bool UART_DataAvailable(void);
uint8_t UART_Receive(void);


#endif /* UART_LIB_H_ */

 

#makefile attiny2313 
AVR         = attiny2313
COMPILAR    = avr-gcc -Wall -O3 -mmcu=$(AVR)

FUENTES     = 019sensorUltrasonidoHCSR04.c UART_LIB.c
SALIDA_HEX  = 019sensorUltrasonidoHCSR04.hex
OBJETOS     = $(patsubst %.c, %.o, $(FUENTES))
SALIDA_ELF  = $(patsubst %.hex, %.elf, $(SALIDA_HEX))

all: $(SALIDA_HEX) size  # <-- Añade 'size' como dependencia

%.o: %.c
	$(COMPILAR) -c $<

$(SALIDA_HEX): $(OBJETOS)
	$(COMPILAR) $^ -o $(SALIDA_ELF)
	avr-objcopy -O ihex $(SALIDA_ELF) $@

# Comando para verificar el tamaño del firmware
.PHONY: size
size: $(SALIDA_ELF)
	@echo "=== Tamaño del firmware ==="
	avr-size --mcu=$(AVR) --format=avr $(SALIDA_ELF)

clean:
	rm -f *.o *.elf *.hex

 

#makefile attiny2313

AVR = attiny2313

PUERTO = /dev/ttyUSB0

PROGRAMADOR = arduino

BAUD = 19200

COMPILAR = avr-gcc -Wall -O3 -mmcu=$(AVR)

FUENTES = 019sensorUltrasonidoHCSR04.c UART_LIB.c

SALIDA_HEX = 019sensorUltrasonidoHCSR04.hex

OBJETOS = $(patsubst %.c, %.o, $(FUENTES))

SALIDA_ELF = $(patsubst %.hex, %.elf, $(SALIDA_HEX))

all: $(SALIDA_HEX)

%.o: %.c

$(COMPILAR) -c $<

$(SALIDA_HEX): $(OBJETOS)

$(COMPILAR) $^ -o $(SALIDA_ELF)

avr-objcopy -O ihex $(SALIDA_ELF) $@

.PHONY: limpiar

limpiar:

rm -f *.o *.elf *.hex

.PHONY: subir

subir: $(SALIDA_HEX)

avrdude -P $(PUERTO) -c $(PROGRAMADOR) -p $(AVR) -b $(BAUD) -U flash:w:$<

 

 

<circuit version="1.1.0-SR1" rev="2051" stepSize="1000000" stepsPS="1000000" NLsteps="100000" reaStep="1000000" animate="1" >

<item itemtype="MCU" CircId="tiny2313-1" mainComp="false" Show_id="false" Show_Val="false" Pos="-124,-40" rotation="0" hflip="1" vflip="1" label="tiny2313-1" idLabPos="0,-20" labelrot="0" valLabPos="-16,20" valLabRot="0" Frequency="1 MHz" Program="019sensorUltrasonidoHCSR04.hex" Auto_Load="false" saveEepr="true" Logic_Symbol="false" Rst_enabled="false" Ext_Osc="false" Wdt_enabled="false" varList="PORTB,DDRB,flag_captura,tiempo_echo" MainMcu="true" SerialMon="-1" />

<item itemtype="SR04" CircId="SR04-2" mainComp="false" Show_id="false" Show_Val="false" Pos="-76,-100" rotation="0" hflip="1" vflip="1" label="SR04-2" idLabPos="-16,-48" labelrot="0" valLabPos="-16,20" valLabRot="0" />

<item itemtype="SerialTerm" CircId="SerialTerm-6" mainComp="false" Show_id="false" Show_Val="false" Pos="-168,-24" rotation="0" hflip="-1" vflip="1" label="SerialTerm-6" idLabPos="-20,-32" labelrot="0" valLabPos="-16,20" valLabRot="0" Baudrate="4800 _Bd" DataBits="8 _bits" StopBits="1 _bits" SerialMon="false" />

<item itemtype="Voltage Source" CircId="Voltage Source-7" mainComp="false" ShowProp="MaxValue" Show_id="false" Show_Val="true" Pos="-200,-100" rotation="0" hflip="1" vflip="1" label="Voltage Source-7" idLabPos="-32,-48" labelrot="0" valLabPos="-8,30" valLabRot="0" Running="false" Value_Volt="3.785 V" MaxValue="5 V" MinValue="0 V" />

<item itemtype="Connector" uid="Connector-9" startpinid="tiny2313-1-PORTD6" endpinid="SR04-2-outpin" pointList="-84,40,-68,40,-68,-52" />

<item itemtype="Connector" uid="Connector-24" startpinid="tiny2313-1-PORTD1" endpinid="SerialTerm-6-pin1" pointList="-132,-16,-144,-16" />

<item itemtype="Connector" uid="Connector-49" startpinid="SR04-2-trigpin" endpinid="tiny2313-1-PORTB7" pointList="-76,-52,-76,-24,-84,-24" />

<item itemtype="Connector" uid="Connector-50" startpinid="Voltage Source-7-outPin" endpinid="SR04-2-inpin" pointList="-172,-84,-172,-124,-164,-124" />

<item itemtype="Connector" uid="Connector-51" startpinid="tiny2313-1-PORTD0" endpinid="SerialTerm-6-pin0" pointList="-132,-24,-144,-24,-144,-32" />

</circuit>

 

Hi.

It would be much easier for both if you just zip the folder containing the files and attach here.

Lazlo_lozla has reacted to this post.
Lazlo_lozla

Hi,

Uploaded files:
arcachofo has reacted to this post.
arcachofo

Seems that the Input Capture Unit is missing the falling edge. I will have a look.

Lazlo_lozla has reacted to this post.
Lazlo_lozla

Hi.
I think this should be solved in last tester build for 1.1.0:
https://simulide.com/p/testers/ 

Lazlo_lozla has reacted to this post.
Lazlo_lozla

I tested the HC-SR04 in rev2069, and it's now working properly. Thank you.

arcachofo has reacted to this post.
arcachofo