1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
| #define USE_SW_SERIAL // comment this line out if you don't use Software Serial
#ifdef USE_SW_SERIAL
#include <SoftwareSerial.h>
const uint8_t RXPin = 2; // the arduino pin on which to receive serial data from your XL-MaxSonar-WRC1
const uint8_t TXPin = 3; // the arduino pin on which to transmit serial data to your XL-MaxSonar-WRC1 (unused, don't connect)
SoftwareSerial maxSonar(RXPin, TXPin);
#else
#define maxSonar Serial // otherwise define here which Hardware Serial Port to use
#endif
// define your baud rate (9600 is the default for XL-MaxSonar-WRC1)
const uint32_t sonarBaudRate = 9600;
const byte buzzPin = 8;
const unsigned int maxDistanceBeep = 600; // in cm. Start beeping if distance less than 6 m
const unsigned int minDistanceBeep = 40; // in cm. continuous beep if distance less than 40 cm
uint16_t distance = 2 * maxDistanceBeep; // large value to avoid beeping at first
// very crude XL-MaxSonar-WRC1 reading interface based on https://www.robotshop.com/media/files/PDF/datasheet-mb7060.pdf
// Serial @ 9600 8N1 (0 - Vcc)
// Frame format: Rxxxx<CR> where xxxx is the distance in cm, start marker is 'R', end marker is a carriage return (ASCII 13)
enum : byte {STARTMARKER, PAYLOAD, ENDMARKER} parserState = STARTMARKER;
bool acquisition() {
static uint16_t payloadDistance;
static uint8_t payloadByteCount;
bool acquired = false;
int rec = maxSonar.read();
if (rec != -1) {
uint16_t byteReceived = rec & 0xFF;
switch (parserState) {
case STARTMARKER:
if (byteReceived == 'R') {
payloadByteCount = 0;
payloadDistance = 0;
parserState = PAYLOAD;
}
break;
case PAYLOAD:
if ((byteReceived >= '0') && (byteReceived <= '9')) {
payloadDistance = 10 * payloadDistance + (byteReceived - '0');
if (++payloadByteCount >= 4) parserState = ENDMARKER;
} else if (byteReceived == 'R') { // handle double 'R'
payloadByteCount = 0;
payloadDistance = 0;
} else parserState = STARTMARKER;
break;
case ENDMARKER:
if (byteReceived == '\r') {
acquired = true;
distance = payloadDistance;
parserState = STARTMARKER;
} else if (byteReceived == 'R') {
payloadByteCount = 0;
payloadDistance = 0;
parserState = PAYLOAD;
} else parserState = STARTMARKER;
break;
}
}
return acquired;
}
void printDistance() {
Serial.print(F("Distance = "));
Serial.print(distance);
Serial.println(F(" cm"));
}
void audioFeedback(uint16_t dist) {
static uint32_t lastTrigger;
if (dist > maxDistanceBeep) digitalWrite(buzzPin, LOW); // pin LOW = pas de beep
else if (dist < minDistanceBeep) digitalWrite(buzzPin, HIGH); // pin HIGH = beep continu
else {
if (millis() - lastTrigger >= dist) {
tone(buzzPin, 1500, 50); // beep a 1500 Hz pendant 50ms
lastTrigger = millis();
}
}
}
void setup() {
Serial.begin(115200);
maxSonar.begin(sonarBaudRate);
pinMode(buzzPin, OUTPUT);
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
if (acquisition()) printDistance();
audioFeedback(distance);
} |