Code
bool motionDetected = 0; // global variable for movement
void gpio_callback(uint gpio, uint32_t events) { //The GPIO callback function to handle interrupts
printf("\nMotion Detected.\n"); //Print message
motionDetected = 1;
}Sam Hutchins
September 2, 2025
Well, I thought I’d make a little update about what I’ve been doing with the LoRa project. I found out that the PIR sensor is severely affected by wind, which seems rather unusual for a thermal sensor, and also affected by bright light. So that kind of puts a crimp in using that particular sensor. So now I am exploring another device, the RCWL-0516 Microwave Motion Sensor.

It is a drop-in replacement for the PIR sensor, requiring no modifications to the circuit board I designed. The technical specifications are simple:
The analog signal can be sampled by an ADC in the Pico, and is proportional to distance. That implies it could be used in robotics. In my case, the 3.3v logic level works fine. As the software sends the weather data once a minute via a delay, that is way too slow to reliably detect the two second pulse from the sensor.

The solution was to use an interrupt. I have historically had issues with interrupts, and could never manage to make them work. However, finally, I did get an interrupt to work, while still collecting and sending the weather data to the Server. Part of the problem when researching any particular website, is everyone has their favorite routine or algorithm. Some work for their purpose, some can be modified. Finally I managed to find a simple set of commands that actually does work. Many times I suspect folks are showing off their knowledge of programming, and make what should be a simple thing as complicated as possible. Having said that, the circuit I found that works really is simple:
The above part is outside of the main() part of the program. The global boolean label motionDetected is passed to the build_packet() function to change the message sent. The printf() statement is only for sending an output to a USB connection, and would not normally be used except for testing. So, instead of the weather being sent, the alarm message replaces it. This required passing the boolean to the build_packet function as so: build_packet(SERVER, CLIENT, identifier, flags, message, motionDetected);. The below statements are within the main() part, toward the top:
/* setup PIR pin for motion detection */
gpio_init(PIR_PIN); // PIR module output signal, detect PIR status
gpio_set_dir(PIR_PIN, GPIO_IN); // PIR_PIN is an input pin
gpio_pull_down(PIR_PIN); // pull down until high signal
gpio_set_irq_enabled_with_callback(PIR_PIN, GPIO_IRQ_EDGE_RISE, true, &gpio_callback); We don’t want the input pin floating, so for reliability, we pull it down internally. As the sensor signal goes high on motion detection, the above acts on GPIO_IRQ_EDGE_RISE. So, the bottom line is simple really is best, as the above statements show. The final piece of the puzzle is the following within the build_packet() function:
The blinkLED() is only eye candy but indicates when motion is detected at the Client, and is mainly for testing. The message line replaces the weather message. So, that about wraps up this little effort/experiment using the LoRa modem in a useful way.
Have a great day, and may the Lord Jesus guide your life in these last days. Bye for now.