Practical use of ultrasonic Sensor with ATMEGA328P and Raspberry PI
Introduction
I2C is a two-wire bus that is designed to be simple, reliable, and energy-efficient. It is often used to connect microcontrollers, sensors, and other peripherals. I2C is also widely used for communication between microcontrollers and external memory.
In this article, we present an alternative to directly using the Raspberry PI GPio to control external devices. I2C makes it possible to consume external data using this communication method. We use an Arduino UNO as a slave I2C device, controlling the HC-SR04 Ultrasonic Sensor, and a Raspberry PI B+ as a master I2C device, consuming the Sensor Data. In addition, the code for both the ATMEGA328P and Raspberry PI B+ has been included.
Connection Diagram
Raspberry as I2C Master Code
#!/usr/bin/env python
from smbus2 import SMBus, i2c_msg
import time
import struct
# bus = smbus.SMBus(1)
address = 0x0A
def read_float_from_arduino(address):
with SMBus(1) as bus:
b = []
for _ in range(4):
b.append(bus.read_byte(address))
f = struct.unpack('f', bytearray(b))
# print([hex(n) for n in b])
# print("{0:4f}".format(f[0]))
return f[0]
if __name__ == '__main__':
bus = SMBus(1)
try:
while True:
float_value = read_float_from_arduino(address)
print("{0:3f} cms".format(float_value))
time.sleep(0.25)
except KeyboardInterrupt:
pass
ATMEGA328P as I2C Slave Code
// I2C Id Address
//Digital Pin for Sensor Trigger
//Digital Pin for Sensor Echo
//General Purpose LED
union FloatUnion {
float number;
uint8_t bytes[4];
} dataToSend;
int byteCount = 0;
int sampleSize = 5;
void setup() {
Wire.begin(I2C_SLAVE_ADDRESS);
Serial.begin(9600);
delay(1000);
// Setup HC-SR04 Sensor
pinMode(TRIGGER, OUTPUT); //Setup TRIGGER as output
pinMode(ECHO, INPUT); //Setup ECHO as input
digitalWrite(TRIGGER, LOW); //Init TRIGGER with 0
// Setup Send and Receive I2C Interrupt Methods
Wire.onRequest(requestEvent);
Wire.onReceive(receiveEvent);
Serial.println("--------- Arduino Configure as Slave on I2C ----------");
dataToSend.number = retrieveAvgMeasureSample(sampleSize);
}
void loop() {
//Serial.println(retrieveAvgMeasureSample(3));
dataToSend.number = retrieveAvgMeasureSample(sampleSize);
delay(10);
}
/*
*
*/
float retrieveSingleMeasure(){
long echoTime; //Time length for echo retrieving
float distance; //Distance in cms
// Send 10us duration pulse
digitalWrite(TRIGGER, HIGH);
delayMicroseconds(10); //Enviamos un pulso de 10us
digitalWrite(TRIGGER, LOW);
echoTime = pulseIn(ECHO, HIGH); //Retrive the echo pulse width
distance = echoTime/59; //Time scaling for a particular distance in cms
delay(100); //Pause for 100ms
return distance;
}
/**
*
*/
float retrieveAvgMeasureSample(int sampleSize) {
float currentSample = 0;
for(int nSample = 0; nSample < sampleSize; nSample++)
currentSample += retrieveSingleMeasure();
return currentSample/sampleSize;
}
/**
*
*/
void requestEvent(){
for(int i = 0; i < 4; i++){
Serial.print(dataToSend.bytes[i], HEX);
Serial.print(" ");
}
Serial.println("");
//
Wire.write(dataToSend.bytes[byteCount++]);
if (byteCount == 4) byteCount=0;
}
/**
*
*/
void receiveEvent(int numBytes) {
for(int i = 0; i < numBytes; i++){
byte byteReceived = Wire.read();
Serial.print(byteReceived, HEX);
Serial.print(" ");
}
Serial.println("");
}
Comments
Post a Comment