Hot answers tagged

11

The pulsein() function is very lossy, in that it is a hard loop and returns a number * the assumed clock cycles it takes for per loop ... // wait for the pulse to stop while ((*portInputRegister(port) & bit) == stateMask) { if (numloops++ == maxloops) return 0; width++; } // convert the reading to microseconds. The loop has been determined // ...


7

From the docs: Reads a pulse (either HIGH or LOW) on a pin. For example, if value is HIGH, pulseIn() waits for the pin to go HIGH, starts timing, then waits for the pin to go LOW and stops timing. Returns the length of the pulse in microseconds. pulsein So, in this case, pulseIn(echoPin, HIGH) starts counting the number of microseconds until ...


5

Regarding the question, “Does PinChangeInt only work on digital pins?”, note that PCI's work on all the digital pins of an ATmega328, and on the first six analog pins. (32-pin '328s have eight analog pins, A0-A7; 28-pin '328s only six, A0-A5.) Regarding the problem symptom that “pulsewidth just seems to increase continuously”, that could happen if for some ...


3

According the official Arduino Reference: PulseIn Fragment: Reads a pulse (either HIGH or LOW) on a pin. For example, if value is HIGH, pulseIn() waits for the pin to go HIGH, starts timing, then waits for the pin to go LOW and stops timing. Returns the length of the pulse in microseconds. Gives up and returns 0 if no pulse starts within a ...


3

Rather than give you the straight answer in code form, consider this approach. If you learn how the unit works, you will be better prepared to answer questions presented to you. The background of an ultrasonic distance measuring device is that it sends out a signal, in the form of sound you cannot hear. The device then listens for any echoes (bounce-back) ...


3

Interrupts don't obey, or even understand the concept of, the "loop" paradigm. An interrupt fires when it needs to fire, and if you're reading a PWM signal then that means it's firing hundreds of times a second. As long as your interrupt is updating a variable that can be read from within the loop, and you ensure that the variable doesn't get updated ...


3

You can't. pulseIn() is a blocking function that waits for a pulse to arrive before returning. Instead you will either have to use interrupts or (where available) Input Capture peripherals. However, using multiple ultrasonic sensors at the same may not make sense. Unless you take great care with your physical design you will get interference between the ...


3

You do not want the reading of the incoming pulse to block your program execution. This is the very key requirement: you want a non-blocking pulse reading. You can write a non-blocking replacement for pulseIn(), but you will have to use it differently. You cannot expect a non-blocking pulseIn() to return the pulse length whenever you call it: instead, it ...


3

pulseIn() is used to Reads a pulse (either HIGH or LOW) on a pin. For example, if value is HIGH, pulseIn() waits for the pin to go HIGH, starts timing, then waits for the pin to go LOW and stops timing. Returns the length of the pulse in microseconds or 0 if no complete pulse was received within the timeout. The timing of this function has been determined ...


2

There's two basic things wrong with what you are doing there: pulseIn() isn't good for very accurate measurements The signal is still happening while you're doing other things, such as printing the high/low times. You're not actually measuring the duty cycle of one single cycle, but the HIGH time of one cycle followed by the low cycle of a later one. If ...


2

I would start by removing Serial interrupts from the pulseIn period. void loop() { pwm_value_H = pulseIn(PWM_PIN, HIGH); pwm_value_L = pulseIn(PWM_PIN, LOW); Serial.println(pwm_value_H); Serial.println(pwm_value_L); D = ((pwm_value_H) / (pwm_value_H + pwm_value_L)) * 100.0; Serial.print("D="); Serial.println(D); Serial.print("...


2

Here is some test data of a pulseIn test. One Arduino sent what were supposed to be 14us pulses, and the other spat out this data: 18,18,18,12,18,18,18,18,18,18,18,18,18,18,18,18,18,24,19,18,18,18,18,18,24,18,18,18,19,18,18,12,18,18,19,18,18,18,18,18,18,18,18,18,18,18,19,18,19,24,18,18,18,18,18,18,18,24,18,18,18,18,18,18,18,18,18,18,18,18,18,19,18,18,18,...


2

You can't use pulseIn() if you want to use both ultrasonic sensors at the same time. So either: don't use pulseIn, and instead do that part yourself using eg. digitalRead, use the ultrasonic sensors sequentially, one then the other, or use pin-change interrupts to sense the signal pulse return. The easiest approach is to use the ultrasonic sensors ...


2

What happens is: You send a pulse of 10 ms with TTL signal. This is the first line in the picture below. Than you call pulseIn. This waits for the echo pulse. The echo pulse will become high when reflected. This happens internally in the module. This is the second line. The echo pulse will stay high depending on the time it took to be echoed back and makes ...


2

There isn't any interrupt code in what you posted. What exactly is the problem? One important note is that you shouldn't try to print to Serial line in the interrupt handler as serial is itself driven from interrupts which are switched off during your handler code. If all you really want to do is to print something every 10ms then you don't need any ...


1

I see 2 ways to go here: You could attach a simple interrupt for rising edge to the pin with attachInterrupt() and count the rising edges with a variable. If the third rising edge is sensed, you have 1 period. To measure the time you can save the starting time of the first rising edge to a variable with micros() (which gives you the time since startup in ...


1

An interrupt off of one of the timers sounds like the easiest way to go. To get a measurement precision of, say 3% at 4ms means sampling every (4000us * .03) = 120us (8.333 KHz). If your code has little else to do, you might get away with clock-watching - micros() ticks every 4us - but you'll need to keep anything else you do between reads of micros() to ...


1

Okay, so pulsing is apparently easy enough. If I just do: digitalWrite(13, HIGH); delay(1000); digitalWrite(13, LOW); delay(1000); It will start recording, then turn off about a second later, start again about a second later, and then repeat. I somehow managed to get a 5 second recording as well. I'm not really sure how this is supposed to work. I need to ...


1

First off a comment on your variable types. It's not the cause of your problem, but just something to watch for in future: int impulsi = 0; This should be voltatile (Edit: I see you updated that, that's ok). unsigned deltaT[3]; unsigned vel = 0; These lack a type. As such the default to int. Your deltaT array should be unsigned long since it stores time....


1

Generating an AM signal is child's play compared to detecting one. To generate a signal you just need to create an oscillation and vary the amplitude, which can very crudely be done with PWM. That's simple. To receive a signal you first need to isolate that signal. There's a huge number of signals and noise around all the time, and you need to tune in to ...


1

AM (Amplitude Modulation) varies the amplitude of the carrier based on the input signal. So, assuming you had some circuitry (LC circuit) to receive a particular carrier frequency and managed to boost the voltage so that it was in the range 0-5v then you would able to feed this to an analog input on the Arduino. AnalogRead requires around 100uS per sample, ...


1

You can trigger on CHANGE, and check in your handler which case it is: attachInterrupt(digitalPinToInterrupt(my_pin), my_handler, CHANGE); (...) void my_handler(void) { if(LOW==digitalRead(my_pin)) { //do_falling(); } else { //do_rising(); } } Another option would be to use a timer to poll your input, ...


1

The keyword you are looking for here is interrupt. What is a pulse but a signal that goes from low to high followed by going from high to low, with some period of time between them? Instead of sitting there waiting for the pulse to arrive then measuring how long it is, which is essentially what pulseIn() does, you need to attach the signal to an interrupt ...


1

Here is some code I used to time a ball running down a ramp: const byte LED = 12; const byte photoTransistor = 2; unsigned long startTime; volatile unsigned long elapsedTime; volatile boolean done; void ballPasses () { // if high, start timing if (digitalRead (photoTransistor) == HIGH) { startTime = micros (); } else { ...


1

The concept is actually quite simple. You need to record the time when the signal goes high, and record the time when it goes low. The pulse width is the difference between the two times. Yes, you can do it with interrupts, but you don't need to if you're not trying to do anything else at the same time. A simple polling code could be something like this: ...


1

It is quite OK to use millis() or micros() inside an ISR. In fact that is an excellent time to do it, because you are recording the time of the event shortly after it happened. Make sure the variable you are saving it to is unsigned long and volatile. Eg. volatile unsigned long whenItHappened; volatile bool eventHappened; void myISR () { whenItHappened ...


1

You should avoid pulseIn for a quadcopter, the main reason being that pulseIn takes too long to execute. pulseIn waits for a pulse to start, then waits until that pulse finishes, and then returns how long it took to finish. Standard RC signals pulse at 50-60Hz, with the "high" part of the signals being between 1 and 2 milliseconds. 60Hz is one pulse per 16 ...


1

I've used plenty of receivers like this with arduino. The operating current is not really an issue; It is drawing power off of the 5v line, not the digital pins, which is capable of 100mA. In any case they usually have an extra "bat" line that you could plug in to a BEC from one of your speed controllers, and then just connect signal and ground lines to the ...


1

Indeed it would be a problem if you started to measure the pulse length 1000 microseconds after it starts. However, this is not how the HC-SR04 sensor works: the sensor is triggered by the falling edge of TRIG, at digitalWrite(trigPin, LOW); the ECHO pulse starts about 0.3 ms after the trigger That's why a delay of 1 ms doesn't affect the measurement ...


Only top voted, non community-wiki answers of a minimum length are eligible