Notifications
Clear all

Pico Robotics: Pololu QTRX Reflectance Sensor

1 Posts
1 Users
0 Reactions
410 Views
THRandell
(@thrandell)
Brain Donor
Joined: 4 years ago
Posts: 265
Topic starter  

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.


   
Quote