The third iteration of my project, "BuzzCane. I've switched out the big, 28-pins, ATmega328-PU for a much smaller yet capable enough, 8-pins, ATTiny85. I'll also be adding a way to give the user a way to control the threshold distance value at which to trigger the buzzer.
According to the datasheet, the ATTiny85, an 8-bit MCU based on the AVR RISC architecture. Chosen by me for it's small size and low cost. It has 8Kb for storing program code (Flash Memory), SRAM (temporary data) of 512 Bytes, EEPROM: 512 Bytes (for storing non-volatile data that persists even after power is turned off),
and has 8 pins, 1 for reset, 1 for VCC, and 1 for GND, leaving us with 5 GPIO pins. It has a clock freq. of up tp 8 MHz, not requiring an external oscillator to work. It also has several power-saving modes for battery-powered applications, as well as a watchdog timer. The length of the MCU is 9.91 mm, width is 6.99 mm,
height is around 4.95 mm including the "legs", its weight is negligible.
In the image above, the numbering convention of the ATTINY is different to that of the Arduino, and so physical pin 5 is pin 0, and physical pin 2 is pin 3. It did take me a few minutes after programming the MCU to figure out why it isn't working and so please keep this alternative numbering convention in mind as you work.
#define TRIG_PIN 0 // ATmega328 pin GPIO28 connected to Ultrasonic Sensor's TRIG pin
#define ECHO_PIN 1 // ATmega328 pin GPIO27 connected to Ultrasonic Sensor's ECHO pin
#define buzzerPin 2 // ATmega328 pin GPIO14 connected to Active Buzzer's positive pin
#define potPin 3 // Analog input pin connected to potentiometer
float duration_us;
uint8_t distance_cm;
bool buzzerActive = false; // Flag to track buzzer activation
// Define reference voltage (assuming 5V for Arduino)
const float referenceVoltage = 5.0;
// Lookup table for voltage-to-threshold mapping (modify values as needed)
const struct {
float minVoltage;
float maxVoltage;
uint8_t threshold_cm;
} voltageThresholds[] = {
{0.1, 0.5, 10},
{0.5, 1.0, 25},
{1.0, 1.5, 50},
{1.5, 2.0, 75},
{2.0, 2.5, 100},
{2.5, 3.0, 125},
{3.0, 3.5, 150},
{3.5, 4.0, 175},
{4.0, 4.5, 200},
{4.5, 5.0, 225},
};
// Number of entries in the lookup table
const int numThresholds = sizeof(voltageThresholds) / sizeof(voltageThresholds[0]);
void setup() {
pinMode(buzzerPin, OUTPUT);
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(potPin, INPUT); // Set potentiometer pin as analog input
delay(500);
}
void loop() {
// Read analog value from potentiometer
int potValue = analogRead(potPin);
// Convert analog value to voltage (consider reference voltage)
float inputVoltage = potValue * referenceVoltage / 1023.0;
// Find threshold distance using lookup table
uint8_t threshold_cm = 0;
for (int i = 0; i < numThresholds; i++) {
if (inputVoltage >= voltageThresholds[i].minVoltage && inputVoltage < voltageThresholds[i].maxVoltage) {
threshold_cm = voltageThresholds[i].threshold_cm;
break;
}
}
// Generate 10-microsecond pulse to TRIG pin
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
// Measure duration of pulse from ECHO pin
duration_us = pulseIn(ECHO_PIN, HIGH);
// Calculate the distance
distance_cm = 0.017 * duration_us;
// Check if distance is within threshold
if (distance_cm <= threshold_cm) {
// Activate buzzer if it's not already active
if (!buzzerActive) {
tone(buzzerPin, 1000); // Activate buzzer (adjust as needed)
buzzerActive = true;
}
} else {
// Deactivate buzzer if it's active
if (buzzerActive) {
noTone(buzzerPin);
buzzerActive = false;
}
}
delay(500);
}