Everything But Your Mind

You have the parts now; let’s put them together. This code will have everything but mind control. Here’s what will happen:

Start the bot, and it plays a sound. You can set a movement threshold with the potentiometer. getAttention() is essentially a dummy function that always returns 50% attention. When you turn the threshold under this, the bot starts moving. The multicolor LED shows the threshold level, from 0% blue to 100% red.

When you stop the bot by turning the threshold above 50%, it will slowly grind to a halt. It’s not really that heavy, but the code is faking inertia. Fake inertia will make the robot move smoothly with mind control.

Connect the parts (Figure 2-27) and upload the code.

Circuit diagram for allbutmind.pde

Figure 2-27. Circuit diagram for allbutmind.pde

Code Structure

This code uses only one global variable, speed. For fake inertia to work, we need to know the last speed the robot was moving at as we slow down. This global variable is used only in loop() to keep the program structure clean. The speed variable is sent to functions as a regular parameter.

The three input sensors are processed with lineDetected(), getAttention(), and getThreshold().

Outputs include servos, LEDs, and speakers. The most important output functions are forward(), turn(), sayReady(), and setBlueToRed(). The rest of the output functions are just helper functions to outputs: pulseServo(), wave(), and setColor().

// allbutmind.pde - a mind controlled robot without mind control
// (c) Tero Karvinen & Kimmo Karvinen http://MindControl.BotBook.com


const int linePin=4;
const int servoLeftPin=3;
const int servoRightPin=2;
const int potPin=A0;
const int redPin=9;
const int greenPin=10;
const int bluePin=11;
const float potMin=14.0-1;        // 1
const float potMax=236.0-5;
const int speakerPin=12;

float speed=0.0;        // 2

void setup()
{
        pinMode(linePin, INPUT);
        pinMode(servoLeftPin, OUTPUT);
        pinMode(servoRightPin, OUTPUT);
        pinMode(potPin, INPUT);
        digitalWrite(potPin, HIGH); // internal pullup
        pinMode(speakerPin, OUTPUT);

        sayReady();        // 3
}

void loop()
{
        while (lineDetected()) turn();

        float at=getAttention();        // 4
        float tr=getThreshold();        // 5
        speed=fakeInertia(speed, at, tr);        // 6

        forward(speed);
}

float fakeInertia(float speed, float at, float tr)
{
        if (at<tr)         // 7
                speed-=0.05;
        else
                speed=at;        // 8
        if (speed<0) speed=0.0;        // 9
        return speed;
}

/*** Inputs ***/

bool lineDetected()
{
        return ! digitalRead(linePin);
}

float getAttention()
{
        return 0.5; // dummy value for testing        // 10
}

float getThreshold()
{
        int x=analogRead(potPin);        // 11
        float tr=(x-potMin)/potMax;      // 12
        setBlueToRed(tr);
        return tr;
}

/*** Outputs ***/

void forward(float speed)
{
        for (int i = 0; i < 10; i++) {
                pulseServo(servoLeftPin, 1500+500*speed);
                pulseServo(servoRightPin, 1500-500*speed);
        }
}

void turn()
{
        for (int i = 0; i < 30; i++) {
                pulseServo(servoLeftPin, 1500+500);
                pulseServo(servoRightPin, 1500+500);
        }
}

void pulseServo(int pin, int microseconds)
{
        digitalWrite(pin, HIGH);
        delayMicroseconds(microseconds);
        digitalWrite(pin, LOW);
        delay(5);
}

void setBlueToRed(float redPercent)
{
        int red=redPercent*255;        // 13
        int blue=(1-redPercent)*255;
        setColor(red, 0, blue);
}

void setColor(int red, int green, int blue)
{
        analogWrite(redPin, 255-red);
        analogWrite(greenPin, 255-green);
        analogWrite(bluePin, 255-blue);
}

void sayReady()
{
        wave(speakerPin, 440, 40);
        delay(25);
        wave(speakerPin, 300, 20);
        wave(speakerPin, 540, 40);
        delay(25);
        wave(speakerPin, 440, 20);
        wave(speakerPin, 640, 40);
        delay(25);
        wave(speakerPin, 540, 40);
        delay(25);
}

void wave(int pin, float frequency, int duration)
{
        float period = 1/frequency * 1000 * 1000; // microseconds
        long int startTime = millis();
        while (millis()-startTime < duration) {
                digitalWrite(pin, HIGH);
                delayMicroseconds(period / 2);
                digitalWrite(pin, LOW);
                delayMicroseconds(period / 2);
        }
}
1

This line and the next specify limits of the potentiometer you measured earlier with hellopot.pde. We’ve shortened the range a bit, so that the user can easily reach the minimum and maximum value. Even though 14 and 236 could be represented as integers, they must be specified as float here. That’s because we use the numbers in division, and we want the results to be floating points. With integers, 1/2=0. But usually, we really want a float, such as 1.0/2.0=0.5.

2

This is a global variable, which could be read and modified from any function. But we don’t do that! We only use this in loop(), and pass it to functions as a parameter.

3

Play a sound.

4

Get the attention level from NeuroSky MindWave. Currently, the dummy function always returns 0.50, meaning 50% attention.

5

Threshold is read from the potentiometer.

6

When attention falls below threshold, we want to stop slowly. Note how we pass speed as a normal parameter, so that fakeInertia() doesn’t have to access the global variable. All speed, attention at, and threshold tr are percentages (such as 63%), represented by floating point numbers (such as 0.63).

7

At low concentration, slow down to a halt.

8

If attention is above threshold, use attention as speed. So maximum attention gets maximum speed.

9

Don’t go backwards.

10

We’ll implement this later. The attention will be read from NeuroSky MindWave headband.

11

analogRead() returns a value from 0 (0V) to 1023 (5V). But this raw value isn’t really convenient to play with.

12

We convert the raw value to percent of the max value possible with our potentiometer. For example, turning it to minimum results in x=14, making tr equal to (14-13)/231.0 = 1/231.0 = 0.0.

13

We show percentage as a color. Zero is blue, one is red. Anything in between is a mixture.

Almost there! After this code, you only have to handle reading attention to finish your mind-reading robot.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
13.58.51.228