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

Quote from Lazlo_lozla on April 20, 2025, 2:00 pm"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>
"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>

Quote from arcachofo on April 21, 2025, 9:54 amHi.
It would be much easier for both if you just zip the folder containing the files and attach here.
Hi.
It would be much easier for both if you just zip the folder containing the files and attach here.


Quote from arcachofo on April 23, 2025, 10:02 amSeems that the Input Capture Unit is missing the falling edge. I will have a look.
Seems that the Input Capture Unit is missing the falling edge. I will have a look.

Quote from arcachofo on April 26, 2025, 2:18 pmHi.
I think this should be solved in last tester build for 1.1.0:
https://simulide.com/p/testers/
Hi.
I think this should be solved in last tester build for 1.1.0:
https://simulide.com/p/testers/

Quote from Lazlo_lozla on April 27, 2025, 1:23 pmI tested the HC-SR04 in rev2069, and it's now working properly. Thank you.
I tested the HC-SR04 in rev2069, and it's now working properly. Thank you.