Remote scanning using an ultrasonic rangefinder
Introduction to the HC-SR04 ultrasonic rangefinder.
The HC-SR04 ultrasonic rangefinder determines the distance to objects using ultrasound at a frequency of 40 kHz. Bats and dolphins do this in the same way. It emits sound at a frequency of 40 kHz and listens to the reflected echo. The distance to the object is calculated based on the time of the sound wave movement back and forth.
The readings of the ultrasonic rangefinder are not affected by the illumination from the sun and the color of the object. It allows you to detect even the transparent surface of an object. Has difficulty measuring distances to fluffy objects.

draw 1. Ultrasonic rangefinder HC-SR04
Configuration of the HC-SR04 rangefinder terminals

HC-SR04 parameters:
- Supply voltage: 5V;
- Silent mode consumption: 2 mA;
- Operating consumption: 15 mA;
- Distance measurement range: from 5 to 400 cm;
- Viewing angle: 30°.
To work with the ultrasonic rangefinder, you need to install the Ultrasonic library from developer Erick Simões. Open the Tools menu and select the Library Management section.

Drawing 2. Tools_
Enter the word "ultrasonic" in the search bar.
Picture 3. Library Manager_
Scroll through the list of libraries and find the library Ultrasonic by Erick Simões.
Picture 4. The Ultrasonic Library by Erick Simões_
Click on the button Installations.
Picture 5. The Installation Button_
Now you can open the test sketch in the menu section File – Examples – Ultrasonic and test the sensor operation.
Sample program code for Arduino
#include <OrbicraftBus.h>
#include <Ultrasonic.h>
* Module HR-SC04 (four pins)
* ---------------------
* | HC-SC04 | Arduino |
* ---------------------
* | Vcc | 5V |
* | Trig | 6 |
* | Echo | 7 |
* | Gnd | GND |
* ---------------------
Message msg;
OrbicraftBus bus;
Ultrasonic ultrasonic(6, 7); // connect HC-SR04 to pins 6 (Trig) and 7 (Echo)
int distance;
int16_t msgSize = 0;
void setup() {
Serial1.begin(9600); // setting the speed of information exchange over Serial1 !!!
}
void loop() {
distance = ultrasonic.read(); // reading the distance
msgSize = bus.takeMessage(msg); // trying to read the message using
the takeMessage if (msgSize > 0) method{ //if there is a message
switch (msg.id ){//depending on the message ID, we perform certain actions
// Consider the case of ID 2
case 0x02:{
String data = String(distance); // writing the distance sensor readings to the data variable
bus.SendMessage(bus.obcAddress, 0, data); // passing the contents of the data variable to the database
break;
}
}
}
}
// The next block of code must always be added to the end of the program
// The function is called automatically and is necessary to process the message
void serialEvent2() {
bus.serialEventProcess();
}
Sample code of the Orbicraft program
#include "libschsat.h"
const float kd = 200.0;
// The time step of the algorithm, with
const float time_step = 0.1;
// The target angular velocity of the satellite, deg/s
. // For stabilization mode is 0.0.
const float omega_goal = 5.0;
// The number of the flywheel
const int mtr_num = 1;
// Maximum permissible flywheel speed, rpm
const int mtr_max_speed = 3000;
// Number of the DUS (angular velocity sensor)
const uint16_t hyr_num = 1;
int16_t mtr_new_speed;
int motor_new_speed_PD(int mtr_speed, int omega, float omega_goal){
/* Function for determining the new flywheel speed.
The new flywheel speed is made up of
the current flywheel speed and the speed increment.
The speed increment is proportional to the angle error and the angular velocity error.
mtr_speed - current angular velocity of the flywheel, rpm
omega - current angular velocity of the satellite, deg/s
omega_goal - target angular velocity of the satellite, deg/s
mtr_new_speed - required angular velocity of the flywheel, rpm*/
mtr_new_speed = (int)(mtr_speed + kd * (omega - omega_goal));
if (mtr_new_speed > mtr_max_speed)
{
mtr_new_speed = mtr_max_speed;
}
else if (mtr_new_speed < -mtr_max_speed)
{
mtr_new_speed = -mtr_max_speed;
}
return mtr_new_speed;
}
void initialize_all(void){
/*The function includes all devices that will be used in the main program.*/
printf("Enable motor no.%d\n", mtr_num);
motor_turn_on(mtr_num);
Sleep(1);
printf("Enable angular velocity sensor №%d\n", hyr_num);
hyro_turn_on(hyr_num);
Sleep(1);
}
void switch_off_all(void){
/* The function disables all devices that will be used in the main program.*/
printf("Finishing...");
int16_t new_speed = mtr_new_speed; //
printf("\nDisable angular velocity sensor no.%d\n", hyr_num);
hyro_turn_off(hyr_num);
motor_set_speed(mtr_num, 0, &new_speed);
Sleep (1);
motor_turn_off(mtr_num);
printf("Finish program\n");
}
void control(void){
char answer[255]; // Creating an array to save the answer
//nt32_t count = 100; // Setting the counter to 5 steps
initialize_all();
// Initializing the flywheel status
int16_t mtr_state;
// Initialize the status of the DUS
int16_t hyro_state = 0;
int16_t pRAW_dataX = 0;
int16_t pRAW_dataY = 0;
int16_t pRAW_dataZ = 0;
int16_t *gx_raw = &pRAW_dataX;
int16_t *gy_raw = &pRAW_dataY;
int16_t *gz_raw = &pRAW_dataZ;
int16_t speed = 0;
int16_t *mtr_speed = &speed;
int16_t omega;
int i;
for(i = 0; i < 500; i++){
int status = arduino_send(0, 2, NULL, answer, 100);
if (status == 0){
printf("%s\r\n", answer);
}
else{
printf("ErrorSend\r\n");
}
//printf("i = %d\n", i);
// Polling of the angular velocity sensor and flywheel.
hyro_state = hyro_request_raw(hyr_num, gx_raw, gy_raw, gz_raw);
mtr_state = motor_request_speed(mtr_num, mtr_speed);
// Processing of angular velocity sensor readings,
// calculation of the angular velocity of the satellite according to the readings of the DUS.
// If the DUS error code is 0, i.e. there is no error
if (!hyro_state){
float gz_degs = *gz_raw * 0.00875;
omega = gz_degs;
}
else if (hyro_state == 1){
printf("Fail because of access error, check the connection\n");
}
else if (hyro_state == 2){
printf("Fail because of interface error, check your code\n");
}
int mtr_new_speed;
//Processing the flywheel readings and setting the required angular velocity.
if (!mtr_state) {
// if the error code is 0, i.e. there is no error
int16_t mtr_speed=0;
motor_request_speed(mtr_num, &mtr_speed);
//printf("Motor_speed: %d\n", mtr_speed);
// setting the new flywheel speed
mtr_new_speed = motor_new_speed_PD(mtr_speed,omega,omega_goal);
motor_set_speed(mtr_num, mtr_new_speed, &omega);
}
}
Sleep(time_step);
switch_off_all();
}
Analysis of the received data
The result of the program will be a large array of data displayed by Orbicraft on the screen. Excel should be used to process this data. Copy the data and paste it into one Excel column. Plot the height graph based on the received data.

Figure 6. Height graph based on the received data_