0

This bot is supposed to begin moving forward when the button is pressed, and stop after counting 3 lines of tape on the ground. Currently it is set up to scan the color of the floor at the beginning and count any major differences as a line of tape. Unfortunately I can't test its tape-sensing capabilities due to not being able to get it to actually start. It will only move if I hold the button down continuously, and stops as soon as I release it. Here is the code and images (It uses the Arduino Pro Mini 3.3v):

#include <SFE_ISL29125.h>
SFE_ISL29125 RGB;
unsigned int master2;
unsigned int detect2;
boolean isOn = false;
unsigned int accumulator = 0;

void setup() {
  RGB.init();
  pinMode(7, INPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  master2 = RGB.readGreen();
}

void loop() {
  if(isOn) {
    if(accumulator < 3) {
      detect2 = RGB.readGreen();
      digitalWrite(8, HIGH);
      digitalWrite(9, LOW);
      if(detect2 <= (master2 - 10) || detect2 >= (master2 + 10)) {
        accumulator++;
      }
    } else {
      accumulator = 0;
      isOn = false;
      digitalWrite(8, LOW);
      digitalWrite(9, LOW);
    }
  } else if(digitalRead(7) == HIGH) {
    isOn = true;
  } else {
    digitalWrite(8, LOW);
    digitalWrite(9, LOW);
  }
}

top-down view bottom view

  • Could you replace the various hard-coded GPIO numbers with constants (e.g. #defines) please? It's hard(er than I can be bothered with) to guess what the various pins do. – Mark Smith Feb 9 '17 at 20:59
  • Pin 7 is the button, pins 8 and 9 are the motor. I really can't be bothered with using constants since I'm rushing to get this done. – Bakna Feb 9 '17 at 21:10
  • Possibly it accumulates so fast that it will immediately stop when you release the button? – Paul Feb 9 '17 at 22:03
  • Could I solve it by increasing the color tolerance? Or switching to one of Parallax's Line Follower Kit sensors that I have lying around? – Bakna Feb 9 '17 at 22:12
  • Rip out the detector code and test it. I strongly suspect your readings are causing problems, and the code to count the three lines is broken anyway. – Mark Smith Feb 9 '17 at 22:20
1

I strongly suspect the main problems with your code are in these lines:

  if(detect2 <= (master2 - 10) || detect2 >= (master2 + 10)) {
    accumulator++;
  }

If I understand correctly, with this code you are attempting to tell whether you have been over a line of tape, which will be indicated by a change in reading from RGB.readGreen(); - say high, low, high. If so, accumulator++. (I have no opinion on whether this is a valid way of sensing it, or how well your sensor will work.)

This is definitely broken in one way, and probably broken in another.

First the definitely-broken way:

You want to sense down-up-down-up-down-up (or up-down-up-down-up-down). Your code senses simply three higher or lower readings. Your loop() takes no time at all, so when your buggy moves onto the tape, it will immediately read (say) high, then loop round, read high again, loop round and read high again, and again. accumulator is now 3 and we stop the motor.

Second, the maybe-broken way:

What value does master2 have? Consider that it is an unsigned integer. You are subtracting 10 from it. What do you get if its value is 5? It can'be be -5 because it is unsigned. How you solve this depends on the possible range of values from RGB.readGreen();. The implementation looks like it could give a value anywhere in the range, so we have to be careful.

Here's my reworking of your code. It assumes the concept of checking for values which vary by 10 from the original value is sensible - I've no idea if it is. (I don't understand what this "middle" values means, but you say you've "already tested the components individually" which I don't believe because your code could never have worked but, assuming you saw something similar working...) It also makes a very big assumption that the value will change cleanly - from higher to lower exactly once per edge of strip, with no wobbling. Log out some values to find whether it really does.

#include <SFE_ISL29125.h>
SFE_ISL29125 RGB;
int master2;
boolean isOn = false;
int changes = 0;

#define BUTTON 7
#define MOTOR_A 8
#define MOTOR_B 9

#define LOWER 0
#define HIGHER 1
int last_state = 0;

void setup() {
  RGB.init();
  pinMode(BUTTON, INPUT);
  pinMode(MOTOR_A, OUTPUT);
  pinMode(MOTOR_B, OUTPUT);
  master2 = (int)(RGB.readGreen()/2);
}

void loop() {
  if(isOn) {
    // Wait for 6 changes: up-down or down-up, three times.
    if(changes < 6) {
      int detect2 = (int)(RGB.readGreen()/2);
      digitalWrite(MOTOR_A, HIGH);
      digitalWrite(MOTOR_B, LOW);
      // Count _changes_ in state only
      if(last_state == HIGHER && detect2 <= (master2 - 5) {
        last_state = LOWER;
        changes++;
      } else if (last_state == LOWER && detect2 >= (master2 + 5)) {
        last_state = HIGHER;
        changes++;
      }
    } else {
      accumulator = 0;
      isOn = false;
      digitalWrite(MOTOR_A, LOW);
      digitalWrite(MOTOR_B, LOW);
    }
  } else if(digitalRead(7) == HIGH) {
    isOn = true;
  } else {
    digitalWrite(MOTOR_A, LOW);
    digitalWrite(MOTOR_B, LOW);
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.