The goal of our project was to build a mechanism that would detect the presence of a person. Specifically, this can help during the pandemic because classmates and teachers can know whether their peers are actually present on zoom when their cameras are off. The device consists of a sonar sensor used to detect the distance between the machine and the person, and a servo motor to turn a wheel that points to whether a person is there or not. Ideally, the mechanism we built would be embedded into the students / teacher computer. Future improvements for the device would be to detect the specific person that is there.
#include <Servo.h> //================================================================ // Hardware definitions. You will need to customize this for your specific hardware. const int sonarTriggerPin = 8; // Specify a pin for a sonar trigger output. const int sonarEchoPin = 7; // Specify a pin for a sonar echo input. const int SERVO_PIN = 9; Servo svo; //================================================================ // Current state of the five output channels. Each may range // from 0 to 100, inclusive. Illegal values will be clamped // to this range on send. The specific relationship between // your sensor inputs and these values will need to be // customized for your hardware. int distance = 0; // Set the serial port transmission rate. The baud rate is the number of bits // per second. const long BAUD_RATE = 115200; // The rated distance limit of the sensor, in cm. const int MAX_DISTANCE = 100; // A typical speed of sound, specified in cm/sec. const long SOUND_SPEED = 34000; // Threshold for when to make a change const int MAKE_CHANGE = 10; // Counter used to detect when a change in the servo should be made. int counter = 0; // Previous value of received message int prevVal = 0; boolean canMove = true; //================================================================ // This function is called once after reset to initialize the program. void setup() { // Initialize the Serial port for host communication. Serial.begin(BAUD_RATE); // Initialize the digital input/output pins. You will need to customize this // for your specific hardware. pinMode(LED_BUILTIN, OUTPUT); pinMode(sonarTriggerPin, OUTPUT); pinMode(sonarEchoPin, INPUT); svo.attach(SERVO_PIN); } //================================================================ // This function is called repeatedly to handle all I/O // and periodic processing. This loop should never be // allowed to stall or block so that all tasks can be // constantly serviced. void loop() { serial_input_poll(); hardware_input_poll(); } //================================================================ // Polling function to process messages received over the // serial port from the remote Arduino. Each message is a // line of text containing a single integer as text. void serial_input_poll(void) { if (Serial.available() > 0) { // When serial data is available, process and interpret // the available text. // This may be customized for your particular hardware. // The default implementation assumes the line contains a single integer // which controls the built-in LED state. int value = Serial.parseInt(); // Change occured in action to move servo if(value != prevVal){ Serial.print("entered eerearac"); counter = 0; prevVal = value; canMove = true; } counter++; if(counter >= MAKE_CHANGE){ if(canMove){ if(value == 1){ linearMove(0, 90, 600); } else { linearMove(90, 0, 600); } canMove = false; } counter = 0; } // Drive the LED to indicate the value. if (value){ digitalWrite(LED_BUILTIN, HIGH); } else { digitalWrite(LED_BUILTIN, LOW); } // Once all expected values are processed, flush any // remaining characters until the line end. Note that // when using the Arduino IDE Serial Monitor, you may // need to set the line ending selector to Newline. Serial.find('\n'); } } //================================================================ // Polling function to read the inputs and transmit data whenever needed. void hardware_input_poll(void) { // Calculate the interval in milliseconds since the last polling cycle. static unsigned long last_time = 0; unsigned long now = millis(); unsigned long interval = now - last_time; last_time = now; // Poll each hardware device. Each function returns // true if the input has been updated. Each function // directly updates the global output state variables // as per your specific hardware. The input_changed flag // will be true if any of the polling functions return // true (a logical OR using ||). bool input_changed = poll_sonar(interval); // Update the message timer used to guarantee a minimum message rate. static long message_timer = 0; message_timer -= interval; // If either the input changed or the message timer expires, // retransmit to the network. if (input_changed || (message_timer < 0)) { message_timer = 1000; // one second timeout to guarantee a minimum message rate transmit_packet(); } } //================================================================ // Poll the sonar at regular intervals. bool poll_sonar(unsigned long interval) { static long sonar_timer = 0; sonar_timer -= interval; if (sonar_timer < 0) { sonar_timer = 250; // 4 Hz sampling rate // Generate a short trigger pulse. digitalWrite(sonarTriggerPin, HIGH); delayMicroseconds(10); digitalWrite(sonarTriggerPin, LOW); // Measure the echo pulse length. The ~6 ms timeout // is chosen for a maximum range of 100 cm assuming // sound travels at 340 meters/sec. With a round trip // of 2 meters distance, the maximum ping time is // 2/340 = 0.0059 seconds. You may wish to customize // this for your particular hardware. const long TIMEOUT = (2 * MAX_DISTANCE * 1000000)/SOUND_SPEED; unsigned long ping_time = pulseIn(sonarEchoPin, HIGH, TIMEOUT); // The default implementation only updates the data if a // ping was observed, the no-ping condition is ignored. if (ping_time > 0) { // Convert to a distance. Note that the speed of sound // is specified in cm/sec, so the duration is scaled // from microsecondst o seconds. The factor of 2 accounts // for the round-trip doubling the time. distance = (ping_time * 1e-6 * SOUND_SPEED) / 2; return true; } } return false; // No change in state. } //================================================================ // Send the current data to the MQTT server over the serial port. // The values are clamped to the legal range using constrain(). void transmit_packet(void) { int moveServo = 0; if(distance <= MAX_DISTANCE / 4){ moveServo = 1; } Serial.println(moveServo); } //================================================================ void linearMove(int start, int end, int duration){ // Specify the number of milliseconds to wait between updates. const int interval = 20; // Calculate the overall angle size that the servo must do // to reach a cycle float angleSize = start - end; if(angleSize < 0){ angleSize *= (-1); } // Compute the size of each step in degrees. float step = angleSize / duration * 15; Serial.println(step); // Declare a float variable to hold the current servo angle. float angle = start; // Begin a do-loop. This always executes the body at least once, and then // iterates if the while condition is met. do { svo.write(angle); // update the servo output delay(interval); // pause for the sampling interval if (end >= start) { angle += step; // movement in the positive direction if (angle > end) angle = end; } else { angle -= step; // movement in the negative direction if (angle < end) angle = end; } } while (angle != end); // Update the servo with the exact endpoint before returning. svo.write(end); }
Leave a Reply
You must be logged in to post a comment.