chatgpt 에게 아두이노 코드의 pulsein 함수를 사용하지 않고 사용하는 방법에 대해 질문 해본 결과입니다.
굉장히 유능한 코드를 보여주고 있습니다.
Yes, it is possible to measure distance using an HC-SR04 ultrasonic sensor without using the pulseIn() function in Arduino.
One way to do this is to use the pulseIn() function to calculate the duration of the pulse, and then convert this duration to a distance. Here's an example code:
chatgpt 는 pulsein함수를 사용하는 방법을 우선 설명해주고 있습니다.
const int trigPin = 9;
const int echoPin = 10;
void setup() {
Serial.begin(9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
void loop() {
long duration, distance;
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = duration * 0.034 / 2;
Serial.print("Distance: ");
Serial.print(distance);
Serial.println(" cm");
delay(500);
}
However, if you don't want to use the pulseIn() function, you can use the pulse timing directly. Here's an example code that demonstrates this approach:
다음으로는 pulsein 함수를 대체하는 방법을 말해주고 있습니다.
const int trigPin = 9;
const int echoPin = 10;
void setup() {
Serial.begin(9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
void loop() {
long duration, distance;
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseTiming(echoPin, HIGH, 10000);
distance = duration * 0.034 / 2;
Serial.print("Distance: ");
Serial.print(distance);
Serial.println(" cm");
delay(500);
}
long pulseTiming(int pin, int level, long timeout) {
long start = micros();
while (digitalRead(pin) != level) {
if (micros() - start > timeout) {
return 0;
}
}
start = micros();
while (digitalRead(pin) == level) {
if (micros() - start > timeout) {
return 0;
}
}
return micros() - start;
}
다음은 인터럽트를 사용해서 사용가능하냐고 질문해보았습니다.
Yes, it is possible to use interrupt functions to measure distance with the HC-SR04 ultrasonic sensor in Arduino.
One way to do this is to use an interrupt function to detect the rising edge of the echo signal, and then use the micros() function to measure the duration of the pulse. Here's an example code:
const int trigPin = 9;
const int echoPin = 10;
volatile long startMicros, endMicros, pulseDuration;
void setup() {
Serial.begin(9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
attachInterrupt(digitalPinToInterrupt(echoPin), echoISR, RISING);
}
void loop() {
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
delay(50);
pulseDuration = endMicros - startMicros;
long distance = pulseDuration * 0.034 / 2;
Serial.print("Distance: ");
Serial.print(distance);
Serial.println(" cm");
delay(500);
}
void echoISR() {
if (digitalRead(echoPin) == HIGH) {
startMicros = micros();
} else {
endMicros = micros();
}
}
질문에 대한 답을 해주고 마무리 설명까지 해줍니다.
In this code, the echoISR() function is triggered by the rising edge of the echo signal, and uses the micros() function to measure the duration of the pulse. The pulse duration is stored in the global variable pulseDuration, which is then used to calculate the distance. The delay(50) in the loop() function allows time for the pulse to be received and processed before the next measurement is taken.
Note that in this example code, the pulse duration is measured in microseconds rather than in milliseconds as in the previous examples. This provides greater accuracy, as micros() has a resolution of 4 microseconds.
아두이노 라이브러리 함수를 사용하지 않고, 원래 사용하던 AVR 코드를 사용해서 SR04 거리센서 측정에 대해
다시 물어보았습니다.
Sure, here is an example AVR code for measuring distance with the HC-SR04 ultrasonic sensor without using Arduino libraries:
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define TRIG_PIN PB1
#define ECHO_PIN PB2
volatile uint16_t pulse_start_time, pulse_end_time;
volatile uint8_t echo_detected = 0;
void setup()
{
// Set up Timer/Counter1 for input capture
TCCR1B |= (1 << ICES1); // capture rising edge
TCCR1B |= (1 << CS10); // no prescaler
TIMSK1 |= (1 << ICIE1); // enable input capture interrupt
// Set up I/O pins
DDRB |= (1 << TRIG_PIN); // set TRIG pin as output
DDRB &= ~(1 << ECHO_PIN); // set ECHO pin as input
// Set up global interrupts
sei();
}
void loop()
{
// Trigger a pulse
PORTB |= (1 << TRIG_PIN); // set TRIG pin high
_delay_us(10); // pulse width > 10 us
PORTB &= ~(1 << TRIG_PIN); // set TRIG pin low
// Wait for echo pulse to be detected
while (!echo_detected) {
// do nothing
}
echo_detected = 0; // clear flag
// Calculate distance from pulse duration
uint32_t pulse_duration = (pulse_end_time - pulse_start_time);
uint16_t distance = pulse_duration * 0.034 / 2;
// Output distance to serial
// ...
}
ISR(TIMER1_CAPT_vect)
{
uint16_t pulse_time = ICR1; // capture timer value
if (TCCR1B & (1 << ICES1)) { // rising edge detected
pulse_start_time = pulse_time;
TCCR1B &= ~(1 << ICES1); // capture falling edge
} else { // falling edge detected
pulse_end_time = pulse_time;
echo_detected = 1; // set flag
TCCR1B |= (1 << ICES1); // capture rising edge
}
}
Wow..