I noticed that @tmatatu is using the Pololu QTR reflectance sensor with Arduino, so I thought that I’d pass along what I’m doing with that sensor on the Pico. The short version is that I had to add: gpio_disable_pulls(sensorPin); to get it to work.
I’m interested in doing some more work on evolving robot controllers, but this time with the coordination of a swarm of robots to move “food” to a “nest”. So my use case is to use one QTRX reflectance sensor https://www.pololu.com/product/4341 to allow the robots to recognize when they are over some dark area (the nest).
It was very straightforward to port the routines I needed from the Pololu QTR Reflectance Sensor Library https://github.com/pololu/qtr-sensors-arduino because my use case is so simple and I’m only using one sensor. I used target_link_libraries(test, pico_stdlib) in the CMakeList.txt file. So nothing very exciting there…
Here’s the code.
/*
This is a watered down version of the Pololu library that runs their QTRX IR
reflectance sensors. I have just a single sensor board of the RC variety so
this is very simple. No dimming of IED or calibration steps or readLineBlack
or readLineWhite calls... Just read raw sensor values.
*/
#include <stdio.h>
#include <stdlib.h>
#include "pico/time.h"
#include "pico/stdlib.h"
#define sensorPin 13 // Out pin on QTRX sensor
#define emitterPin 14 // Control pin on QTRX sensor
uint16_t qtrxTimeout = 2500; // 2500us
void emitterOn(uint16_t emitter) {
gpio_put(emitter, 1); // set emitter pin to HIGH
sleep_us(300);
return;
}
void emitterOff(uint16_t emitter) {
gpio_put(emitter, 0); // set emitter pin to LOW
sleep_us(1200);
return;
}
uint16_t readQTRX() {
uint16_t sensor = qtrxTimeout;
uint16_t time;
uint64_t startTime;
gpio_set_dir(sensorPin, GPIO_OUT); // set direction of GPIO to out
gpio_put(sensorPin, 1); // drive pin high
sleep_us(10); // charge line for 10 us
startTime = time_us_64();
time = 0;
gpio_set_dir(sensorPin, GPIO_IN); // set direction of GPIO to in
while (time < qtrxTimeout) {
time = time_us_64() - startTime;
if ((gpio_get(sensorPin) == 0) && (time < sensor))
sensor = time; // record the first time the line reads low
}
return sensor;
}
void readSensor(uint16_t *sensorValue) {
emitterOn(emitterPin);
*sensorValue = readQTRX(sensorPin);
emitterOff(emitterPin);
return;
}
int main()
{
stdio_init_all();
gpio_init(sensorPin); // Emable I/O set to GPIO_SIO and set to input.
gpio_init(emitterPin);
gpio_set_dir(emitterPin, GPIO_OUT);
gpio_disable_pulls(sensorPin);
uint16_t sensorValue;
printf("waiting for usb host");
while (!stdio_usb_connected()) {
printf(".");
sleep_ms(500);
}
sleep_ms(2000);
while (true) {
readSensor(&sensorValue);
printf("voltage went low in %ld us\n", sensorValue);
// Larger sensor values mean less reflectance, lower values more reflectance.
sleep_ms(250);
}
}
Tom
To err is human.
To really foul up, use a computer.