Tart Robotics
Published © GPL3+

A DIY Tangible Coding Robot

Tangible Coding provides an opportunity for kids to become involved in programming with no screen used.

IntermediateFull instructions provided3 hours5,065

Things used in this project

Story

Read more

Schematics

Schematic diagram of the robot circuit

Schematic diagram of the coding console circuit

Code

Tangible Coding Robot

C/C++
/*
  Tangible Coding Robot
    The idea:
    In this project, we will show you how to make a tangible programmable robot out of Lego Technic pieces,
    Arduino boards, off-the-shelf DC motors, and NRF communication modules.
    The current project uses two Arduino Nano boards as the main controller of the
    robot and the programming console, respectively
    The circuit:
    - In this circuit, an Arduino Nano is used. Any other types of Arduino
    can be used of course but do not forget to change the pin configurations
    if you want to change the circuit on your preference.
    Visit the Tart Robotics blog for more information:
    https://www.tartrobotics.com/blog
*/

#define motorRightA A0
#define motorRightB A1
#define motorRightPWM 6
#define motorLeftA A2
#define motorLeftB A3
#define motorLeftPWM 5

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <Servo.h>
RF24 radio(9, 10); // CE, CSN

// Setup Adafriut Neopixel LED Ring
#include <Adafruit_NeoPixel.h>
#define PIXELSPIN 4
#define NUMPIXELS 16
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIXELSPIN, NEO_GRB + NEO_KHZ800);

const byte address[6] = "00010";
const int motorSpeed = 80, straightTimeDelay = 600, turningTimeDelay = 560;


void setup() {
  radio.begin();
  radio.openReadingPipe(0, address);
  radio.setPALevel(RF24_PA_MIN);
  radio.startListening();
  pixels.begin(); // Adafriut Neopixel begin
  for (int i = 0; i < 17; i++) {
    pixels.setPixelColor(i, pixels.Color(0, 0, 0));
    pixels.show();
  }
}

void loop() {

  if (radio.available()) {
    // Take and decode instructions
    char instructions[50] = "";
    radio.read(&instructions, sizeof(instructions));

    for (int i = 0; i < sizeof(instructions); i++) {
      char message = instructions[i];
      stopTheRobot();
      delay(200);
      if (message == 'f') {
        goForward();
      } else if (message == 'b') {
        goBackward();
      } else if (message == 'r') {
        goRight();
      } else if (message == 'l') {
        goLeft();
      } else if (message == 's') {
        stopTheRobot();
        break;
      }
    }
  }
}

void goForward() {
  digitalWrite(motorRightA, LOW);
  digitalWrite(motorRightB, HIGH);
  analogWrite(motorRightPWM, motorSpeed);
  digitalWrite(motorLeftA, HIGH);
  digitalWrite(motorLeftB, LOW);
  analogWrite(motorLeftPWM, motorSpeed);

  pixels.setPixelColor(6, pixels.Color(200, 200, 190));
  pixels.setPixelColor(7, pixels.Color(200, 200, 190));
  pixels.setPixelColor(8, pixels.Color(200, 200, 190));
  pixels.setPixelColor(9, pixels.Color(200, 200, 190));
  pixels.setPixelColor(10, pixels.Color(200, 200, 190));
  pixels.show();

  delay(straightTimeDelay);
  for (int i = 0; i < 17; i++) {
    pixels.setPixelColor(i, pixels.Color(0, 0, 0));
    pixels.show();
  }
}
void goBackward() {
  digitalWrite(motorRightA, HIGH);
  digitalWrite(motorRightB, LOW);
  analogWrite(motorRightPWM, motorSpeed);
  digitalWrite(motorLeftA, LOW);
  digitalWrite(motorLeftB, HIGH);
  analogWrite(motorLeftPWM, motorSpeed);

  pixels.setPixelColor(0, pixels.Color(0, 200, 0));
  pixels.setPixelColor(1, pixels.Color(0, 200, 0));
  pixels.setPixelColor(2, pixels.Color(0, 200, 0));
  pixels.setPixelColor(14, pixels.Color(0, 200, 0));
  pixels.setPixelColor(15, pixels.Color(0, 200, 0));
  pixels.show();

  delay(straightTimeDelay);
  for (int i = 0; i < 17; i++) {
    pixels.setPixelColor(i, pixels.Color(0, 0, 0));
    pixels.show();
  }
}
void goLeft() {
  digitalWrite(motorRightA, LOW);
  digitalWrite(motorRightB, HIGH);
  analogWrite(motorRightPWM, motorSpeed);
  digitalWrite(motorLeftA, LOW);
  digitalWrite(motorLeftB, HIGH);
  analogWrite(motorLeftPWM, motorSpeed);

  pixels.setPixelColor(2, pixels.Color(0, 0, 210));
  pixels.setPixelColor(3, pixels.Color(0, 0, 210));
  pixels.setPixelColor(4, pixels.Color(0, 0, 210));
  pixels.setPixelColor(5, pixels.Color(0, 0, 210));
  pixels.setPixelColor(6, pixels.Color(0, 0, 210));
  pixels.show();

  delay(straightTimeDelay);
  for (int i = 0; i < 17; i++) {
    pixels.setPixelColor(i, pixels.Color(0, 0, 0));
    pixels.show();
  }
}
void goRight() {
  digitalWrite(motorRightA, HIGH);
  digitalWrite(motorRightB, LOW);
  analogWrite(motorRightPWM, motorSpeed);
  digitalWrite(motorLeftA, HIGH);
  digitalWrite(motorLeftB, LOW);
  analogWrite(motorLeftPWM, motorSpeed);

  pixels.setPixelColor(10, pixels.Color(200, 0, 0));
  pixels.setPixelColor(11, pixels.Color(200, 0, 0));
  pixels.setPixelColor(12, pixels.Color(200, 0, 0));
  pixels.setPixelColor(13, pixels.Color(200, 0, 0));
  pixels.setPixelColor(14, pixels.Color(200, 0, 0));
  pixels.show();

  delay(straightTimeDelay);
  for (int i = 0; i < 17; i++) {
    pixels.setPixelColor(i, pixels.Color(0, 0, 0));
    pixels.show();
  }
}
void stopTheRobot() {
  digitalWrite(motorRightA, HIGH);
  digitalWrite(motorRightB, HIGH);
  analogWrite(motorRightPWM, 0);
  digitalWrite(motorLeftA, HIGH);
  digitalWrite(motorLeftB, HIGH);
  analogWrite(motorLeftPWM, 0);
}

Tangible Coding Console

C/C++
/*
  Tangible Coding Console
    The idea:
    In this project, we will show you how to make a tangible programmable robot out of Lego Technic pieces,
    Arduino boards, off-the-shelf DC motors, and NRF communication modules.
    The current project uses two Arduino Nano boards as the main controller of the
    robot and the programming console, respectively
    The circuit:
    - In this circuit, an Arduino Nano is used. Any other types of Arduino
    can be used of course but do not forget to change the pin configurations
    if you want to change the circuit on your preference.
    Visit the Tart Robotics blog for more information:
    https://www.tartrobotics.com/blog
*/

#define forward_button 8
#define backward_button 4
#define right_button 7
#define left_button 5
#define startstop_button 6
#define buzzerPin A0
#define auxGnd A2 //auxiliary ground pin

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(9, 10); // CE, CSN

const byte address[6] = "00010";

void setup() {
  radio.begin();
  radio.openWritingPipe(address);
  radio.setPALevel(RF24_PA_MIN);
  radio.stopListening();
  pinMode(auxGnd, OUTPUT);
  pinMode(buzzerPin, OUTPUT);
  digitalWrite(auxGnd, LOW);
}

void loop() {
  //Take the instructions (50 instructions in a row maximum)
  char instructions[50];
  for (int i = 0; i < sizeof(instructions); i++)
    instructions[i] = NULL;

  boolean runTheProgram = false;

  int i = 0;
  while (i < sizeof(instructions)) {
    buzz(100);
    while (true) {
      if (!digitalRead(forward_button)) {
        while (!digitalRead(forward_button));
        instructions[i] = 'f';
        break;
      } else if (!digitalRead(backward_button)) {
        while (!digitalRead(backward_button));
        instructions[i] = 'b';
        break;
      } else if (!digitalRead(left_button)) {
        while (!digitalRead(left_button));
        instructions[i] = 'r';
        break;
      } else if (!digitalRead(right_button)) {
        while (!digitalRead(right_button));
        instructions[i] = 'l';
        break;
      } else if (!digitalRead(startstop_button)) {
        while (!digitalRead(startstop_button));
        runTheProgram = true;
        break;
      }
    }
    i++;
    if (runTheProgram)
      break;
  }
  instructions[i] = 's';
  buzz(800);
  radio.write(&instructions, sizeof(instructions));
}

void buzz(int duration) {
  digitalWrite(buzzerPin, HIGH);
  delay(duration);
  digitalWrite(buzzerPin, LOW);
}

Credits

Tart Robotics

Tart Robotics

15 projects • 50 followers
Our mission is to provide children with novel robotic tools, to inspire them to become future innovators.

Comments