Introduction: Advanced Makeblock Sensors (DIY)

The Makeblock platform contains all kinds of mechanical parts and electronics to create robots. Makeblock sells these robots as a part of their STEM education platform. And through the Scratch language, children can acquire basic programming skills. The microcontrollers used in these robots are fully Arduino compatible. This makes them easy to extend with all kind of components.

This Instructable is about using the Makeblock robots with the Arduino programming environment. This is a logical choice, for those who have outgrown programming with Scratch.

It starts with the different Makeblock boards: The mCore and the Auriga. And explains the relationship between Makeblock port numbers and Arduino pins.

The next part contains simple programs to use the Makeblock sensors and LEDs. The Makeblock library is introduced, in combination with the Arduino programming environment.

Then this instructable deals with the used RJ25 connectors and cables. And explains how to connect Adafruit components to the Makeblock mainboards. Including how to program these components.

In the end, this Instructable describes how to make sensors and displays for the Makeblock robot yourself. And with a modified connector it's even possible to connect two sensors to a single port.

Some of these sensors can also be used within the Scratch programming language.


I've called this Instructable "Advanced Makeblock Sensors" because it's not a 'default' Makeblock Instructable. It's about Arduino programming, in combination with the internal hardware components. The first examples are very basic (blinking LED), but there is a certain order in the examples. Each example goes a little further than the previous one.

The NeoPixel ring proved to be the most useful DIY component. It behaves like a normal Makeblock component, and can be used in any programming environment. I made two of them, which now serve as the robot's 'eyes'.

Step 1: Parts

The following Makeblock parts are used in this instructable:

The following Adruino sensors and displays are used:


The RJ25 to Dupont wire can be used to connect all kind of Arduino sensors and displays to the Makeblock robot.

Step 2: Programming Tools

There are three different ways to program a Makeblock robot. And they each have their own level of difficulty. This makes the Makeblock robots suitable for starters, intermediates and advanced programmers.

The first method is an App on a tablet (Android and iOS). The App contains a number of lessons to teach the basics of skratch.This is done by graphical programming through games. It's also posible to make small programs with skratch.

The next step is the mBlock software (Windows, Mac OS and Chrome OS). This is the same graphical programming language as used in the App. The Scratch program is translated into an Arduino sketch. Which has to be uploaded to the main-board using an USB-cable. There are examples and lessons on the Makeblock site to get you started.

The final and advanced stage is the Arduino programming environment using the Makeblock libraries. This environment uses the Arduino C derived programming language. It requires to download the Makeblock libraries from Github.
The Auriga board is fully compatible with an Arduino Mega, and the mCore board is compatible with an Arduino Uno. As a result, the boards are not limited to the Makeblock parts. It's also possible to use Adafruit parts, including usage of their software libraries. This method gives complete freedom programming the microcontroller.


The main advantage of Makeblock parts versus Adafruit parts are the connectors. It is not necessary to solder, and everything works with the same wires. In addition, all Makeblock drivers are in a single library.

Step 3: Makeblock Library

This instructable is about working with the different Makeblock parts. And there is a lot of documentation available on their website.

Using the Arduino programmer with Makeblock requires to use a software library. This library contains all functions to access the different sensors. The Makeblock-libraries can be downloaded from Github.

The Makeblock-library contains many examples. These have to be adjusted to the board type (MeAuriga, MeMCore). After that, they will show how easily the hardware can be used.


Library Class Example

The following list contains all public functions for the MeBuzzer Class.

      MeBuzzer ()
      MeBuzzer (uint8_t port)
      MeBuzzer (uint8_t port, uint8_t slot)
void  setpin (int pin)
void  tone (int pin, uint16_t frequency, uint32_t duration)
void  tone (uint16_t frequency, uint32_t duration=0)
void  noTone (int pin)
void  noTone ()

The class contains 4 functions: MeBuzzer, setpin, tone and noTone. Some functions are listed more than once. This is called function overloading. These functions can be used with different parameter types.

Each function has its own meaning:

  • The MeBuzzer-function is used to create a buzzer object. It accepts a RJ25 port number (PORT_n), and optionally a slot number (Each RJ25 port has 2 slots to attach a sensor).
  • The setpin-function can be used to connect the sensor with an Arduino pin.
  • The tone-function causes the buzzer to make a sound. It requires a frequency and a duration.
  • The noTone-function stops all sound.

Arduino Sketch Example

The following program example shows almost all parts of an arduino sketch:

// (1) Select the Makeblock library for your board:
#include <MeAuriga.h> // <MeMCore.h>

// (2) Constants and Variables: 
#define BUZZER_PORT 45
int distance;

// (3) Create objects for the sensors: 
MeUltrasonicSensor ultra (PORT_6); 
MeBuzzer           buzzer;

// (4) Put your setup code here, to run once:
void setup()
{
  buzzer.setpin(BUZZER_PORT); // The buzzer has no RJ25 connector.
  buzzer.noTone();
}

// (5) Put your main code here, to run repeatedly:
void loop()
{
  // Measure the distance in centimeters
  distance = ultra.distanceCm(); // 0 to 400 cm

  // Play 3 tones, duration depends on distance.
  buzzer.tone(587, distance * 2); // D5
  buzzer.tone(659, distance * 2); // E5
  buzzer.tone(523, distance * 2); // C5       

  delay(100);
}

Further in this Instructable are more examples about how to use the library. There are also many examples in the Makeblock library.

Step 4: Arduino IDE

The Arduino software can be downloaded from the Arduino-website. Start the installer and install all components.

Download the Makeblock library from Github. Read the "How to use" to install the library. Or just copy the makeblock-folder to your arduino default library-folder.

Step 5: MCore Mainboard

The mCore board is based on an Arduino Uno. The main differences are the additional onboard modules:

  • Buzzer
  • Light sensor
  • Button
  • Two WS2812 LEDs
  • Two PWM motor controllers
  • IR receiver
  • IR emitter
  • Blue LED
  • Blue tooth module
  • Four color-labelled RJ25 connectors

This provides an easy way to start learning programming. There is no need to make electrical circuits, all sensors are present, or are easily connected with RJ25 connectors.


To use the mCore with the Arduino programming environment, it is necessary to identify the port numbers. The ports are defined inside the Makeblock library. And the MeCore.h file shows all port definitions:

MePort_Sig mePort[17] =
{
  { NC, NC }, { 11, 12 }, {  9, 10 }, { A2, A3 }, { A0, A1 },
  { NC, NC }, {  8, A6 }, { A7, 13 }, {  8, A6 }, {  6,  7 },
  {  5,  4 }, { NC, NC }, { NC, NC }, { NC, NC }, { NC, NC },
  { NC, NC },{ NC, NC },
};

The ports are stored in an array with 17 entries. And each port is a collection of two Arduino pins. This array and the electronic diagram (mCore.pdf) gives the following list:

Port_1    { 11 , 12 } = RJ25 port 1
Port_2    {  9 , 10 } = RJ25 port 2
Port_3    { A2 , A3 } = RJ25 port 3
Port_4    { A0 , A1 } = RJ25 port 4
Port_5    { NC , NC }  (Not Connected)
Port_6    {  8 , A6 } = Buzzer, Light sensor
Port_7    { A7 , 13 } = Button, two WS2812 LEDs
Port_8    {  8 , A6 } = Buzzer, Light sensor
Port_9    {  6 ,  7 } = PWM motor 2, DIR Motor 2
Port_10   {  5 ,  4 } = PWM motor 1, DIR Motor 1

mCore Port 6 and 8 have the same definition.

The following sensors don't have a port number defined in the library. They can be used using the Arduino pin number:

2   = IR Receiver
3   = IR emitter LED
5   = light sensor
13  = Blue LED

The four mCore RJ25 connectors are labelled with different colors. The Makeblock sensors are also labeled with one or more colors. These colors should match when connecting a sensor to a port.

The mCore ports have four possible colors, which indicate the different sensor types which can be used:

  1. Black: Single analog port or two analog ports.
  2. Blue: Two digital ports.
  3. Yellow: Single digital port.
  4. White: I2C Port

Sensors with a black label can't be used with port 1 and 2. The Arduino pins for these ports are digital only (9, 10, 11 and 12). And these can't handle analog signals from the black-labeled sensors.


There is a small difference between ports 1 and 2. The arduino ports 3, 5, 6, 9, 10 and 11 are PWM ports, and pin 12 isn't.

Step 6: Auriga Mainboard

The Auriga board is the latest Makeblock board. It's an updated version of the Orion board. And can be compared with an Arduino Mega/2560. Just like the mCore, the Auriga has multiple onboard additional features:

  • Temperature sensor
  • Sound sensor
  • Gyroscope
  • Passive buzzer
  • Two encoder motor drivers
  • Two light sensors
  • Blue LED
  • WS1282 LED ring
  • Color-labelled RJ25 connectors
  • Bluetooth module

Using the Arduino software with the Auriga requires to identify the port numbers. These are defined inside the Makeblock library. The MeAuriga.h file contains an array which defines all ports. Each Makeblock port is connected to two Arduino pins. These pins are identified as slot1 and slot2.

MePort_Sig mePort[15] =
 {
Port 0  {  NC,  NC }   Not connected
Port 1  {   5,   4 }   red
Port 2  {   3,   2 }   red
Port 3  {   7,   6 }   red
Port 4  {   9,   8 }   red
Port 5  {  16,  17 }   grey
Port 6  { A10, A15 }   universal
Port 7  {  A9, A14 }   universal 
Port 8  {  A8, A13 }   universal
Port 9  {  A7, A12 }   universal
Port 10 {  A6, A11 }   universal 
Port 11 {  NC,  A2 }   light sensor 1
Port 12 {  NC,  A3 }   light sensor 2
Port 13 {  NC,  A0 }   temperature sensor
Port 14 {  NC,  A1 }   sound sensor
 }

Universal port 6 is connected to analog port 10 and analog port 15 of the microcontroller.

Not all pins are defined in this array. These parts are accessible by using the Arduino pin numbers:

44 = 12 x ws12812 LED
45 = Buzzer
13 = Blue LED

Although the motor drivers are accessed through a library, it might be useful to know the port numbers:

ENA A  = pin 19
ENA B  = pin 42
PWMA   = pin 11
DIR A2 = pin 49
DIR A1 = pin 48

ENB A  = pin 18
ENB B  = pin 43
PWMB   = pin 10
DIR B1 = pin 47
DIR B2 = pin 46

Although this is a lot of information, it does not mean programming the Makeblock components is difficult. It is especially important to know which part is connected to which port. This is specified once when defining the object. After that, this information is no longer necessary.


There is an servo port on this board (Arduino pin D16/TX2 and D17/RX2). But this is covered by the expansion board.

Step 7: Sketch: LEDs

The first sketch example is very simple. It controls two LEDs on the Auriga board. These are the small red and blue LEDs located near the USB connector. I haven't found any reference to these LEDs in the Makeblock library. And it requires the usage of the Arduino default port functions to program these LEDs.

The first action is to determine which ports are connected to these LEDs. This requires an electronic schedule. This is a graphical representation of all electronic components. The two LEDs are listed in the 程序更新&无线遥控 (program updates & wireless remote control) part. They are connected to the D0/RX0 and D1/TX0 ports of the MEGA2560 microcontroller. The primary use of these LEDs is to visualise serial communication over these ports.

The anodes of the LEDs are connected at +5 Volts. And the LED is turned on when the corresponding port value is connected to the ground. This equals the digital value LOW.

The following sketch makes the LEDs blink.:

//Auriga Board

int BlueLed = 0;
int RedLed  = 1;

void setup()
{
  pinMode( BlueLed, OUTPUT);
  pinMode( RedLed, OUTPUT);
}

void loop()
{
  digitalWrite( BlueLed, LOW);
  digitalWrite( RedLed, HIGH);
  delay (1000);
  digitalWrite( BlueLed, HIGH);
  digitalWrite( RedLed, LOW);
  delay (1000);
}

Each Arduino sketch requires 2 void type functions: setup and loop. The setup method is ran once after the Arduino is powered up. This is where you want to do any initialisation steps. The loop method is ran continuously afterwards. This is the place for all code you want to run over and over again. The required varables are declared above the setup method.


The D0/RX0 and D1/TX0 ports are also connected to the BLE (Bluetooth Low Energy) and UART modules (Universal Asynchronous Receiver/Transmitter). Directly controlling the LEDs will disrupt usage of these modules. That will be the reason for not including these LEDs in a library.

Step 8: Sketch: Pin 13

Almost every Arduino has an built-in LED attached to pin 13. And the mCore and Auriga boards are no exception. This LED can be controller by a scratch program or an Arduino sketch:

// mCore and Auriga

int BlueLed = 13;

void setup()
{
  pinMode( BlueLed, OUTPUT);
}

void loop()
{
  digitalWrite( BlueLed, HIGH);
  delay (1000);
  digitalWrite( BlueLed, LOW);
  delay (1000);
}

The blue LED is located underneath the Auriga extension board.


Digital pin 13 is harder to use as a digital input than the other digital pins. Because of this LED.

Attachments

Step 9: Measuring Distance

Both the mBot and mBot Ranger robots have an ultrasonic sensor to measure distance.

The sensor emits an ultrasound which travels through the air, and if there is an object on the way it will bounce back to the module. The transmission speed of the sonic wave in the air is 340 m/s (equals 34 cm/ms or 0.034 cm/µs). The time recorded by the sensor, can be used to calculate the distance to the object.

If there is an object at 1000 µs (1 ms), the time to the object is 500 µs (half the distance). This gives a distance of 500 µs * 0.034 cm/µs = 17 cm.

There is no math required to use this sensor. The Makeblock library takes care of this, with the following classes:

        MeUltrasonicSensor (void)
        MeUltrasonicSensor (uint8_t port)
void    setpin (uint8_t SignalPin)
double  distanceCm (uint16_t=400)
double  distanceInch (uint16_t=180)
long    measure (unsigned long=30000)

Use the MeUltrasonicSensor class to create an object. And use one of the functions to measure the distance.


The following code measures the distance using a mCore board (source = UltrasonicSensorTest.ino):

#include "MeMCore.h"

// create an object named ultrasensor 
MeUltrasonicSensor ultraSensor(PORT_1); 

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  Serial.print("Distance : ");
  Serial.print(ultraSensor.distanceInch() );
  Serial.printInch(" inch");
  delay(100);
}

The maximum distance is 400 cm or 180 inch.

Step 10: Sketch: Buzzer

Both the mCore and Auriga boards contain a buzzer. And this step was supposed to be the first library example. Unfortunately the "BuzzerTest.ino"-example didn't work as it should. And this gives a great opportunity to dive into the Makeblock drivers.

The following sample-code gives some small "clicks" from the auriga board (soure: BuzzerTest.ino):

#include "MeAuriga.h"

void setup() 
{
}

void loop()
{
  buzzerOn();
  delay(1000);
  buzzerOff();
  delay(1000);
}

Not exactly what I expected. A look at the MeBuzzer class reference doesn't reveal a buzzerOn and buzzerOff function. And the same example for the mCore gives an error about these fuctions not being declared

The driver for MeBuzzer module contains the following classes:

      MeBuzzer ()
      MeBuzzer (uint8_t port)
      MeBuzzer (uint8_t port, uint8_t slot)
void  setpin (int pin)
void  tone (int pin, uint16_t frequency, uint32_t duration) 
void  tone (uint16_t frequency, uint32_t duration=0)
void  noTone (int pin)
void  noTone ()

There are nu functions called buzzerOn and BuzzerOff in this class!

Looking at the "MeAuriga.h"-file shows two additional functions at the end of the file. Someone hardcoded these functions into the Auriga definition file (these functions aren't in the mCore-definition).

#define buzzerOn()  pinMode(45,OUTPUT),digitalWrite(45, HIGH)
#define buzzerOff() pinMode(45,OUTPUT),digitalWrite(45, LOW)

Adding these functions to the MeMCore.h gives the same "clicks" on the mCore board (change port 45 into port 8).


There are two types of buzzers:

  1. Active buzzer: generates the sound itself. Just turn it on to make a sound, and turn it off to stop the sound.
  2. Passive buzzer: Requires an AC signal. The tone has to be generated at the source

It looks like the buzzerOn/buzzerOff-code expects an active buzzer. Make the pin high for a sound, and low to turn it off. But both the mCore and Auriga board have a passive buzzer. This requires a signal to get a sound.

The Auriga uses pin 45 for the buzzer, this is a PWM port. The analogwrite function can be used to write a PWM wave. The following code writes a square pulse at about 500Hz (Arduino's PWM frequency).

#define buzzerOn()  pinMode(45,OUTPUT),analogWrite(45, 127)
#define buzzerOff() pinMode(45,OUTPUT),analogWrite(45, 0)

This doesn't work for the mCore board, because pin 8 isn't a PWM output port.


The MeBuzzer Class contains the real functions to get a tone (the buzzerOn and buzzerOff functions are not in this library). This library is used by the "MbotBuzzerTest.ino" example. The Driver (MeBuzzer.cpp) for Me Buzzer module contains the code to play a tone:

void MeBuzzer::tone(int pin, uint16_t frequency, uint32_t duration)
{
  buzzer_pin = pin;
  int period = 1000000L / frequency;
  int pulse = period / 2;
  pinMode(buzzer_pin, OUTPUT);
  for (long i = 0; i < duration * 1000L; i += period) 
  {
    digitalWrite(buzzer_pin, HIGH);
    delayMicroseconds(pulse);
    digitalWrite(buzzer_pin, LOW);
    delayMicroseconds(pulse);
    wdt_reset();
  }
}

The code creates the required output wave to get the requested tone. And requires two input parameters: frequence and duration. The output tone is determined by the frequency:

        |  0 |  1 |  2 |  3 |  4 |  5 |  6  |  7  |  8  |  9  |
--------+----+----+----+----+----+----+-----+-----+-----+-----+
c       |  16|  33|  65| 131| 262| 523| 1046| 2093| 4186| 8372|
cis/des |  17|  35|  69| 139| 277| 554| 1108| 2217| 4434| 8869|
d       |  18|  37|  73| 147| 294| 587| 1174| 2349| 4698| 9397|
dis/es  |  19|  39|  78| 156| 311| 622| 1244| 2489| 4978| 9956|
e       |  21|  41|  82| 165| 330| 659| 1318| 2637| 5274|10548|
f       |  22|  44|  87| 175| 349| 698| 1396| 2793| 5587|11175|
fis/ges |  23|  46|  92| 185| 370| 740| 1479| 2959| 5919|11839|
g       |  24|  49|  98| 196| 392| 784| 1567| 3135| 6271|12543|
gis/as  |  26|  52| 104| 208| 415| 831| 1661| 3322| 6644|13289|
a       |  28|  55| 110| 220| 440| 880| 1760| 3520| 7040|14080|
ais/bes |  29|  58| 117| 233| 466| 932| 1864| 3729| 7458|14917|
b       |  31|  62| 123| 247| 494| 988| 1975| 3951| 7902|15804|

The following example plays some tones on the Auriga board:

#include <MeAuriga.h>    // mCore: MeMCore.h

MeBuzzer buzzer;
#define BUZZER_PORT 45   // mCore 8

void setup() 
{
  buzzer.setpin(BUZZER_PORT);
  buzzer.noTone();
}

void loop() 
{
  buzzer.tone(262, 250);   //NOTE_C4
  buzzer.tone(294, 250);   //NOTE_D4
  buzzer.tone(330, 250);   //NOTE_E4
  delay(2000);

  buzzer.tone(587, 250);   //NOTE_D5
  buzzer.tone(659, 250);   //NOTE_E5
  buzzer.tone(523, 250);   //NOTE_C5
  delay(2000);
}

The first 3 tones are from the Auriga firmware.


The modified buzzerOn and buzzerOff functions have one advantage over the tone-function. The tone-functions creates an output wave, and the next command is executed after the tone duration.

The buzzerOn function creates a PWM signal, and continues with the next commands. The PWM signal continues until the buzzerOff function is called.

Step 11: MCore LEDs

The mCore board contains two ws2812 LEDs. These are connected to Arduino port 13. This is the same pin as the build-in small blue test LED.

The LEDs are mapped to the second slot of port 7:

Port7    { A7 , 13 } = button, two WS2812 LEDs

The following sketch uses the Makeblock MeRGBLed-library to alter colors of the LEDs:

#include "MeMCore.h"

#define red        255,000,000
#define blue       000,000,255

MeRGBLed led(PORT_7, 2);  
                             
void setup()
{
}

void loop()
{
  led.setColorAt (0, blue);
  led.setColorAt (1, red);
  led.show();
  delay (100);
  led.setColorAt (0, red);
  led.setColorAt (1, blue);
  led.show();
  delay (100);
}

A "led" object is created by a function call to the MeRGBLed-function. The internal connection is handled by port 7, with the default slot number 2. The second number in the function call determines the number of LEDs. There are 2 LEDs, numbered 0 and 1.

The led.setColorAt-function changes the color for a single LED inside the "led"-object. The LED number and RGB values must be specified inside the call to the function.

Step 12: Auriga Extension Board

The extension board (panel board) contains 12 LEDs (ws2812), a power button and two light sensors.

Because the LEDs do not have a port number, we have to access them via the Arduino pin number. The following code creates an LED object (meRGBLed), and during the setup the pin number and number of LEDs is specified (setpin and setNumber).

#include "MeAuriga.h"

#define amber      255,194,000
#define orange     255,165,000
#define vermillion 227,066,052
#define red        255,000,000
#define magenta    255,000,255
#define purple     128,000,128
#define indigo     075,000,130
#define blue       000,000,255
#define aquamarine 127,255,212
#define green      000,255,000
#define chartreuse 127,255,000
#define yellow     255,255,000
#define white      000,000,000
#define black      255,255,255

#define LEDNUM  12
#define LEDPORT 44

MeRGBLed led(0);
                             
void setup()
{
  led.setpin(LEDPORT);
  led.setNumber(LEDNUM);
}

void loop()
{
  for (int i=0; i<12; i++)
  {
  led.setColorAt ((i   )%12, amber      );
  led.setColorAt ((i+ 1)%12, orange     );
  led.setColorAt ((i+ 2)%12, vermillion );
  led.setColorAt ((i+ 3)%12, red        );
  led.setColorAt ((i+ 4)%12, magenta    );
  led.setColorAt ((i+ 5)%12, purple     );
  led.setColorAt ((i+ 6)%12, indigo     );
  led.setColorAt ((i+ 7)%12, blue       );
  led.setColorAt ((i+ 8)%12, aquamarine );
  led.setColorAt ((i+ 9)%12, green      );
  led.setColorAt ((i+10)%12, chartreuse );
  led.setColorAt ((i+11)%12, yellow     );
  led.show();
  delay (1000);
  }
}

Step 13: Electronic Add-on Pack for Starter Robot Kit

There are several expansion packages for the Makeblock robots. Including several mBot add-on packages. I myself bought a package with 7 sensors, and an 8 x 16 LED display. This makes the number of possible electronic circuits almost endless. It's an expansion package for the starter robot kit. But the sensors work with all Makeblock robots.

The following parts are included:

Prices of this add-on Pack vary per supplier, I've bought my expansion package at Gearbest. The Makeblock-price is about $30.

A number of these sensors are used in the following steps.

Step 14: Me RGB LED

The Me RGB LED contains four WS2812 LEDs. The color of each LED can be set by the altering red-, green-, and blue-values with the driver. Each color has 256 levels of brightness, giving (256 x 256 x 256) 16777216 possible color combinations.

I've used the same LEDs in a previous Instructable (Illuminated Christmas Tree Ornament) with usage of the Adafruit_NeoPixel-library. Makeblock has included these LEDs in their own library. The following example uses this library.

There are some library code-examples available, but with help of the documentation, the LEDs are easy to control:

         MeRGBLed (void)
         MeRGBLed (uint8_t port)
         MeRGBLed (uint8_t port, uint8_t led_num)
         MeRGBLed (uint8_t port, uint8_t slot, uint8_t led_num)
         ~MeRGBLed (void)
void     reset (uint8_t port)
void     reset (uint8_t port, uint8_t slot)
void     setpin (uint8_t port)
uint8_t  getNumber (void)
cRGB     getColorAt (uint8_t index)
bool     setColorAt (uint8_t index, uint8_t red, uint8_t green, uint8_t blue)
bool     setColor (uint8_t index, uint8_t red, uint8_t green, uint8_t blue)
bool     setColor (uint8_t red, uint8_t green, uint8_t blue)
bool     setColor (uint8_t index, long value)
void     setNumber (uint8_t num_led)
void     show (void)

These are all functions inside the MeRGBLed Class. There are different ways to define the LEDs:

  1. Call the MeRGB function with a port number. This defaults to slot2 with 32 LEDs.
  2. Call the MeRGB function with a port number and the number of LEDs. This defaults to slot2.
  3. Call the MeRGB function with a port number, slot number and the number of LEDs.

The following example uses the third function:

#include "MeAuriga.h"

MeRGBLed led(PORT_6, SLOT2, 4);  

int R[14] = {255,255,227,255,255,128,075,000,127,000,127,255,000,255};
int G[14] = {194,165,066,000,000,000,000,000,255,255,255,255,000,255};
int B[14] = {000,000,052,000,255,128,130,255,212,000,000,000,000,255};

void setup()
{
}

void loop()
{
  for(int c = 0; c < 14; c++)
  {
    for(int t = 0; t < 4; t++)
    {
      led.setColorAt(t, R[c], G[c], B[c]);
    }
    led.show();
    delay(1000);
  }
}

This example uses the most specific functions. Slot2 is the default slot number, this can be omitted. And the setColor function can be used instead of the setColorAt function. This changes the color of all LEDs in one call, which makes the inner for loop (t) unnecessary.

#include "MeAuriga.h"

MeRGBLed led(PORT_6, 4);  

int R[14] = {255,255,227,255,255,128,075,000,127,000,127,255,000,255};
int G[14] = {194,165,066,000,000,000,000,000,255,255,255,255,000,255};
int B[14] = {000,000,052,000,255,128,130,255,212,000,000,000,000,255};

void setup()
{
}

void loop()
{
  for(int c = 0; c < 14; c++)
  {
    led.setColor(R[c], G[c], B[c]);
    led.show();
    delay(1000);
  }
}

Both programs have the same output: four color changing LEDs.

Step 15: MePotentiometer

This sensor can be used to adjust rotational speed of a motor, or the brightness of a LED lamp.

The following sketch reads an analog value and displays the output on a 7 segment display.

#include "MeAuriga.h"

MePotentiometer myPotentiometer(PORT_6);
Me7SegmentDisplay disp(PORT_7);

void setup()
{
}

void loop()
{
  disp.display( myPotentiometer.read() );
  delay(100);
}

The analog output value is between 0 and ~980.

This example shows the simplicity of working with the Makeblock library. You do not have to worry about drivers. Attaching the sensors to the Auriga board is easy. This allows you to focus completely on programming the robot. And focus on the use of the sensors, rather than programming the sensors.


The maximum output voltage is lower than 5 Volt (VCCin) because of Diode D1 in the diagram. This diode is the anti-reverse protection for the power supply. Without this diode the maximum value would be 1023.

Step 16: MeJoystick

The MeJoystick contains two potmeters. And can be compared with a double MePotentiometer.

The following example is based on the Makeblock "MeJoystickTest" example:

#include "MeAuriga.h"

MeJoystick joystick(PORT_6);

float angle = 0;     /* The relative angle of XY */
float OffCenter = 0; /* offset with the center */

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  /* read the both joystick axis values: */
  angle = joystick.angle();
  OffCenter = joystick.OffCenter();

  Serial.print("  angle =");
  Serial.print(angle);
  Serial.print("  OffCenter= ");
  Serial.println(OffCenter);

  delay(10);
}

The original example also shows the X and Y values of the potmeters. But the most interesting parts of this library are the angle and offcenter functions. These indicate the direction (in degrees) and the distance from the center of the joystick. This can directly be translated to direction and speed.


Each Makeblock port has two pins. The Joystick uses both pins for the X and Y axis. These type of joysticks also have a button. This joystick has such an button, but it's not connected to one of the pins.

Step 17: Me RJ25 Adapter

The Me RJ25 Adapter module converts the RJ25 port into two input/output ports. Each output port is connected to VCC, GND and a pin of the microcontroller (S1 = Slot1, S2 = Slot2). It's posible to solder some breakout pins, to access all six pins (VCC, GND, S1, S2, SDA, and SCL).

The function list of the MePort class contains the following functions for input and output:

dRead(1)  - Read digital signal from SLOT1
dRead(2)  - Read digital signal from SLOT2 
dWrite(1) - Write digital signal to SLOT1
dWrite(2) - Write digital signal to SLOT2
aRead(1)  - Read analog signal from SLOT1
aRead(2)  - Read analog signal from SLOT1
aWrite(1) - Write analog signal to SLOT1
aWrite(2) - Write analog signal to SLOT2 

This module can be used for NeoPixel LEDs and servo motors. It's posible to connect other Adafruit components, but the RJ25 to Dupont Wire is easier to use.


This board is designed to be used with a blue, yellow of grey connector. It is possible (not recommended) to connect this board to a red connector. But this reverses the polarity. VCC becomes ground, and ground becomes VCC.

This is probably the the reason why the Makeblock sensors have an anti-reverse protection diode. The same polarity would give a too high voltage on a sensor, when it's connect wrongly into a red connector. Remember that VCC can be between 6 and 12 volt.

This adapter uses a CJ3402 mosfet as anti-reverse-protection. The analog values range from 0 to 1023.

Step 18: RJ25 Connector

All mBot electronic modules use a RJ25 connector (Registered Jack). These connectors are commonly used in telecommunication networks. The connector has six contact points and uses 6 wires. The RJ11 and RJ14 connectors have the same size, but have less contact points. It is possible to use non-Makeblock cables, but always check the number of wires.

Each Auriga port has 6 pins: SCL, SDA, GND, VCC, S1 and S2. Not all modules use all of these ports. Some only use the VCC, GND, and a single data port. The table below gives an overview of most sensors. The color indicator on the sensor gives an indication of the ports used.

                   |  1  |  2  |  3  |  4  |  5  |  6  | Port
                   | SCL | SDA | GND | VCC | S1  | S2  | Color
-------------------+-----+-----+-----+-----+-----+-----+-----------
4 Button           |     |     | GND | 5V  |     | OUT | black
7 Segment Display  |     |     | GND | 5V  | DIO | CLK | blue
Compass Sensor     | SCL | SDA | GND | 5V  | KEY | LED | white
Flame Sensor       |     |     | GND | 5V  | A0  | D0  | black
Gas Sensor         |     |     | GND | 5V  | A0  | D0  | black
Gyro Sensor        | SCL | SDA | GND | 5V  | ADO | INT | white
Infrared Receiver  |     |     | GND | 5V  | STA | DAT | blue
Joystick           |     |     | GND | 5V  | X   | Y   | black
Light Sensor       |     |     | GND | 5V  |     | A0  | black
Line Follower      |     |     | GND | 5V  | D0  | D1  | blue
PIR Sensor         |     |     | GND | 5V  | MOD | D0  | blue
Potentiometer      |     |     | GND | 5V  |     | A0  | black
RGB LED            |     |     | GND | 5V  |     | SIG | yellow
RJ25 Adapter       | SCL | SDA | GND | 5V  | S1  | S2  | 
Sound Sensor       |     |     | GND | 5V  |     | A0  | black
TFT Screen         | SCL | SDA | GND | 5V  |     |     | blue/grey
Temperature Sensor |     |     | GND | 5V  |     | DAT | yellow
Touch Sensor       |     |     | GND | 5V  | TOG | OUT | blue
Ultrasonic Sensor  |     |     | GND | 5V  | TRG | SIG | yellow

There are six colors which indicate the required port functions:

  • Red: Output voltage of Vin (6-12 Volt), one or two digital ports.
  • Black: Single analog port or two analog ports.
  • Blue: Two digital ports.
  • Yellow: Single digital port.
  • White: I2C Port
  • Grey: Hardware serial port.

All listed modules can be used on any of the 5 Volt sensor-ports of the Auriga. The mCore board has some limitations. This board is based on an Arduino Uno, and is limited in the number of analog ports.

Step 19: RJ25 to Dupont Wire

The RJ25 to Dupont Wire can be used to connect Makeblock modules to an Arduino. But they can also be used to connect Arduino components to the Makeblock boards. This makes it posible to use sensors from other manufacturers. Where the Me RJ25 adapter uses 4 pins (GND, VCC, S1 and S2), this wire can be used to connect all 6 pins. Including the I2C pins.

I've used this wire for prototyping the DIY-Makeblock electronic modules. The image shows a RJ25 adapter and the dupont connectors. The wires are connected as in the following table:

Blue       SCL      I2C clock bus	
yellow     SDA      I2C data bus
green      GND      Grounding 
red        VCC      5 Volt   
black      S1       Digital/analog port
white      S2       Digital/analog port

Step 20: DIY Temperature and Humidity Sensor

The first DIY sensor is a copy of an existing Makeblock sensor. It's a Temperature and Humidity Sensor which came with an Arduino DIY kit. The non-makeblock version can be used as a regular Makeblock part, with the use of a RJ25 to Dupont Wire. And there is no need to alter any software.

The original sensor has a yellow ID, which means it uses a single digital port. The used sensor uses 3 pins: GND, VCC and Signal. These pins correspend with pins 3, 4 and 6 (S2) of the RJ25 connector. Fortunately, the pins on the circuit board have the same order as the connector. This makes it easy to solder the connector to the board.

Desolder the pin headers from the sensor and remove pins 1, 2 and 5 from the RJ25 connector. Bend the remaining connector pins a little, and solder them on the board. The lower part of the connector should be at the same level as the lower part of the sensor.

Push the pins of the connector into the corresponding holes of the 3D-printed base plate. And glue the sensor circuit board to the plate.

Use the "MeHumitureSensorTest1.ino" example to test te sensor:

#include "MeAuriga.h"

MeHumiture humiture(PORT_6);

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  humiture.update();
  Serial.print("Humidity (%) =");
  Serial.print( humiture.getHumidity() );
  Serial.print(", Temperature (oC) =");
  Serial.println( humiture.getTemperature() );
  Serial.println("###########################");
  delay(1000);
}

By holding the sensor, the temperature rises. Exhaling towards the sensor also ensures higher humidity:

Humidity (%) =43, Temperature (oC) =22
###########################
Humidity (%) =43, Temperature (oC) =22
###########################
Humidity (%) =43, Temperature (oC) =23
###########################
Humidity (%) =43, Temperature (oC) =25
###########################
Humidity (%) =53, Temperature (oC) =26
###########################
Humidity (%) =59, Temperature (oC) =28
###########################

It's also possible to use the RJ25 to Dupont Wire. Green = GND, Red = VCC and white = Signal.

The DIY sensors don't have reverse polarity protection.

Step 21: NeoPixel LEDs

Makeblock sells addressable RGB LED strips that come packed with 15 LEDs (0.5M) or 30 LEDs (1M). These have to be used with a RJ25 Adapter.

The Auriga board can provide up to 3A to drive a RGB LED strip. Each LED uses about 60mA, giving a maximum of about 50 LEDs. This is the current when the strip lights up with maximum brightness. A number of 60 LEDs should be possible, but the MeRGBLed library is limited to 32 LEDs (DEFAULT_MAX_LED_NUMBER-variable).

The MeRGBLed-driver isn't limited to Makeblock parts. It is posible to buy these LEDs at Aliexpress, but this requires some soldering. Makeblock beams are made from metal, use the IP67 Waterproof LEDs which are inside a Silicone Tube.


This step uses an Adafruit NeoPixel ring with 12 LEDs. The goal is to create a NeoPixel ring module with a RJ25 connector (without adapter). These are the same LEDs as on the Auriga expansion board, but this version can be placed almost anywhere on the robot. And also works with the mCore.

The required RJ25 pins are: GND (3), VCC (4) and S2 (signal, 6). Remove the unused connector pins 1,2 and 5. Short wires must be soldered between the RJ25 connector and the led ring. Use shrink wire to insulate the solder points at the RJ25 connector. The wires should go through the opening in the base-plate, before soldering them to the NeoPixel ring.

Test the LEDs and glue all parts together.


The following code is for the mCore robot:

#include "MeMCore.h"

#define amber      255,194,000
#define orange     255,165,000
#define vermillion 227,066,052
#define red        255,000,000
#define magenta    255,000,255
#define purple     128,000,128
#define indigo     075,000,130
#define blue       000,000,255
#define aquamarine 127,255,212
#define green      000,255,000
#define chartreuse 127,255,000
#define yellow     255,255,000
#define white      000,000,000
#define black      255,255,255

MeRGBLed led(PORT_3, SLOT2, 12);  

void setup()
{
}

void loop()
{
  for (int i=0; i<12; i++)
  {
  led.setColorAt ((i   )%12, amber      );
  led.setColorAt ((i+ 1)%12, orange     );
  led.setColorAt ((i+ 2)%12, vermillion );
  led.setColorAt ((i+ 3)%12, red        );
  led.setColorAt ((i+ 4)%12, magenta    );
  led.setColorAt ((i+ 5)%12, purple     );
  led.setColorAt ((i+ 6)%12, indigo     );
  led.setColorAt ((i+ 7)%12, blue       );
  led.setColorAt ((i+ 8)%12, aquamarine );
  led.setColorAt ((i+ 9)%12, green      );
  led.setColorAt ((i+10)%12, chartreuse );
  led.setColorAt ((i+11)%12, yellow     );
  led.show();
  delay (2000);
  }
}

It is possible to place these LED rings in series. A second connector would be required for this (input and output). But this increases the chance of mistakes.
And further in the instrucable, I describe how you can connect two of these LED rings to a single port.

Step 22: 8 X 8 LED Display

This output module is based on a regular 8 x 8 LED display from an Arduino DIY kit. It contains a MAX7219 controller and 64 red LEDs.

The board has 5 pins, and uses the I2C clock for communication. This module can be connected as listed in the following table:

01  +5v                    =  Pin 4
02  GND                    =  Pin 3
03  DIN (DATA)             =  Pin 6 (Slot 2)
04  CS (Chip Select/LOAD)  =  PIN 2 SDA
05  CLK (CLOCK)            =  Pin 1 SCL 

Pin 5 of the RJ25 connector isn't used and can be removed. Pin 6 is in the wrong position, bend it straight forward. Solder the other pins on the board (+5V, GND, CS and CLK).

Finally, solder a piece of wire between the middle hole (DIN) and pin 6 of the connector. It is possible to bend the pen, but this is easier.

There is no Makeblock library available for this module. The driver can be downloaded from Github.


The following Arduino code is a based on one of the examples from the library. It turns all LEDs on and off in a infinite loop. The code expects an Arduino board.

#include "LedControl.h"

// DataIn, CLK, LOAD, NRDEV
LedControl lc=LedControl(12, 11, 10, 1);
   
void setup() 
{
  lc.shutdown(0,false);
  lc.setIntensity(0,8);
  lc.clearDisplay(0);
}
 
void loop() 
{ 
  for(int row=0;row<8;row++) 
  {
    for(int col=0;col<8;col++) 
    {
      lc.setLed(0,row,col,true); 
      delay(20);
    }
  }

  for(int row=0;row<8;row++) 
  {
    for(int col=0;col<8;col++) 
    {
      lc.setLed(0,row,col,false); 
      delay(20);
    }
  }
}

This Arduino example has to be altered before it can be used with a mCore or Auriga board. The LedControl function requires 4 input parameters: DataIn, CLK, LOAD, NRDEV. The number of MAX9217 devices equals 1 (NRDEV). The other values depend of the board type and the port number.

For the Auriga board at port 6:

DataIN = A15 (Port 6, slot 2) = pin A15
CLK    = D21/SCL              = pin 21
LOAD   = D20/SCA              = pin 20

// DataIn, CLK, LOAD, NRDEV
LedControl lc=LedControl(A5, 20, 21, 1);

And the mCore board at port 2:

DataIN = D12 (Port 2, slot 2) = pin 10
CLK    = SCL/PCint13          = pin A5
LOAD   = SDA/PCint12          = pin A4

// DataIn, CLK, LOAD, NRDEV
LedControl lc=LedControl(12, 13, 12, 1);

The module uses the I2C Port, this translates to a white labeled connector. Only the DataIn-pin changes when using another port number.

Step 23: Dual RJ25 Adapter

Although some sensors only use a single data line, it is physically impossible to connect two of these sensors to a single port. This might be a constraint for some projects. And it would be usefull to combine some sensors on the same port.

In particular, the following ports could be combined:

                   |  1  |  2  |  3  |  4  |  5  |  6  | Port
                   | SCL | SDA | GND | VCC | S1  | S2  | Color
-------------------+-----+-----+-----+-----+-----+-----+-----------
4 Button           |     |     | GND | 5V  |     | OUT | black
Light Sensor       |     |     | GND | 5V  |     | A0  | black
Potentiometer      |     |     | GND | 5V  |     | A0  | black
RGB LED            |     |     | GND | 5V  |     | SIG | yellow
Sound Sensor       |     |     | GND | 5V  |     | A0  | black
Temperature Sensor |     |     | GND | 5V  |     | DAT | yellow

The yellow ID means that the module uses a single-digital port. A black ID means that it uses a single-analog port. All off the above sensors use a single port, and always port S2. To combine two sensors, it is required to connect one of these sensors to port S2. And the other sensor onto port S1.

This requires some customization in the Makeblock drivers. The software doesn't expect any values from the other port. The simplest way is to copy an existing driver. And create an alternative version. A structural solution is to pass the slot number to the Makeblock driver. With a default value of S2, for backwards compatibility.

Step 24: Dual RJ25 Adapter - Drivers

The "PotentiometerTest" sketch creates a new object with "MePotentiometer myPotentiometer(PORT_6);". This translates to the analog pin numbers A10 (slot 1) and A15 (slot 2).

The called function in the MePotentiometer.cpp-file only accepts the port number, and not the slot (S1 or S2) position. The next call is to the MePort-function, with only the port-value:

MePotentiometer::MePotentiometer(uint8_t port) : MePort(port)

This port value is passed to the MePort function, without any slot value:

uint8_t MePort::pin(uint8_t port, uint8_t slot)
{
  return(slot == SLOT_1 ? mePort[port].s1 : mePort[port].s2);
}

And empty slot value always returns the "mePort[port].s2" value. Giving the analog pin number A15.

This is why the Makeblock library always expects the potmeter to be on slot S2. And it always has to use slot 2, by the hardware design of the sensor. Nobody at Makeblock ever could have thought that someone would want to use port S1 for the sensor.


The MeRGBLed driver is capable of receiving the slot-number, and the number of LEDs:

MeRGBLed::MeRGBLed(uint8_t port, uint8_t slot, uint8_t led_num) : MePort(port)
{
  if(slot == SLOT1)
  {
    pinMask     = digitalPinToBitMask(s1);
    ws2812_port = portOutputRegister(digitalPinToPort(s1) );
    // set pinMode OUTPUT */
    pinMode(s1, OUTPUT);
  }
  else
  {
    pinMask     = digitalPinToBitMask(s2);
    ws2812_port = portOutputRegister(digitalPinToPort(s2) );
    // set pinMode OUTPUT */
    pinMode(s2, OUTPUT);
  }
  setNumber(led_num);
  _port = port;
  _slot = slot;
}

Parts of this code can be used to modify the MePotentiometer-driver. After this it is still not possible to use these modified drivers in Skratch. This requires to alter the Skratch code.

By cleverly combining the modules, it is possible to connect multiple sensors to a single port. Without modifications in the library. For example, a temperature sensor (default on slot 2) and an RGB LED (select slot 1) can be combined without problems. Or two ws2812 RGB led displays, which both use the meRGBLed drivers.

Step 25: Dual RJ25 Adapter Example

This example combines a potentiometer and a RGB LED module on a single port. The first sensor requires a black port (analog) and the LEDs require a yellow (digital) port. Both parts together require a black/yellow port. For the mCore this means port 3 or port 4.

It's posible to define two objects on the same port number, if they use different slot numbers. The MyPotmeter driver always uses slot 2. This leaves slot 1 for the LEDs. The following commands create both objects on Port 3 of a mCore board:

  • MeRGBLed myLed (PORT_3, SLOT1, 4);
  • MePotentiometer myPotentiometer (PORT_3);

Hereafter both objects can be addressed with their names myLed and myPotentiometer.

The following example uses the potentiometer as a dimmer for the LEDs:

#include "MeMCore.h"

// Yellow port required:
MeRGBLed myLed(PORT_3, SLOT1, 4);  

// Black port required:
MePotentiometer myPotentiometer(PORT_3);

int potValue;
int ledValue;

void setup()
{
}

void loop()
{
  potValue = myPotentiometer.read();
  ledValue = map(potValue, 0, 990, 0, 255);

  myLed.setColorAt(0, ledValue/8, ledValue/8, ledValue/8);
  myLed.setColorAt(1, ledValue, 0, 0);
  myLed.setColorAt(2, 0, ledValue, 0);
  myLed.setColorAt(3, 0, 0, ledValue);
  myLed.show();

  delay(100);
}

The output value of the potentiometer doesn't match the input parameter for the LEDs. This is solved by the map-function, this translates the values between 0 to 990 to a value between 0 and 255.


Most of the Makeblock classes contain a setpin-function. This can be used to alter the pin number after creating the object in the program.

The following example creates two objects on port 3. And both are initally defined on slot 2. The slot number of one of the objects is altered, during the setup in the program. This gives the LEDs on slot 2 and the potentiometer on slot 1. This is the same code as the previous example, with the connected components at different slot numbers.

#include "MeMCore.h"

// Yellow port required:
MeRGBLed myLed(PORT_3, SLOT2, 4);  

// Black port required:
MePotentiometer myPotentiometer(PORT_3);

int potValue;
int ledValue;

void setup()
{
  // Select Arduino pin A2, equals PORT_3, SLOT1
  myPotentiometer.setpin (A2);
}

void loop()
{
  potValue = myPotentiometer.read();
  ledValue = map(potValue, 0, 990, 0, 255);

  myLed.setColorAt(0, ledValue/8, ledValue/8, ledValue/8);
  myLed.setColorAt(1, ledValue, 0, 0);
  myLed.setColorAt(2, 0, ledValue, 0);
  myLed.setColorAt(3, 0, 0, ledValue);
  myLed.show();

  delay(100);
}

Step 26: Simple Dual RJ25 Adapter

After the prototype with dupont wires, a simple adapter has been made. The SDA and SCL pins aren't connected. This gives 4 lines to solder. The middle connector has 4 pins: GND, VCC, S1 and S2. The other connectors have only 3 pins: GND, VCC and S2.

First, all unused pins are removed from the connector. The connector with 4 pins is placed in the middled. This is the wire to the mCore/Auriga board. The connector to the left has pin 6 (S2) connected to pin 6 of the middle connector. And the connector at the right has pin 6 (S2) connected to pin 5 (S1) of the middle connector.

Mark the port at the right with a sticker. Sensors on this connector have to be adressed as slot 1.

Step 27: LEGO Parts

There are never enough parts when building a robot. It is possible to buy metal parts or print them with an 3D printer.

Another alternative is LEGO. The distances between the Makeblock screw holes are a multiple of 8 mm. This corresponds to lego sizes. And LEGO parts are stronger than 3D printed parts. But keep in mind that metal is stronger than LEGO.

Not only the standard lego beams are handy, but also the panel plates (3 x 11 or 5 x 11) are very useful.

Step 28: Electrical Insulator

All makeblock electrical parts are made from printed circuit board (PCB). And most of the solder points aren't isolated. As a result, there is a chance of a short circuit through the metal Makeblock parts. Therefore white areas, on the sensors, indicate which parts are insulated. The sensors can only be mounted onto the beams at these places.

It is possible to design Makeblock plates, and to print them with a 3D printer. Sam Kass made a "MakeBlock Parametric Straight Bracket" on thingiverse. However, printing parts takes quite a while, and they are less strong than the original metal parts.

I've designed some small plates, which can be used as an insulator. This allows the sensors to be placed at all possible places, without regard to the white surfaces.

Step 29: DIY Color Sensor

I noticed some code for a RGB sensor when I started using the Makeblock libraries. And Makeblock didn't have a color sensor at that moment. This is where I got the Idea to create my own sensors (which resulted in this Instructable).

Soon aftere ordering an Adafruit RGB Color Sensor, Makeblock released the MeColor Sensor. And this is a good sign, it means that Makeblock still takes the mCore products seriously.

There isn't much information about the Makeblock sensor, but the product description states: "The module's interface port is a standard blue-and-white, and uses I2C protocol for communication". And the code (MeColorSensor.cpp) reveals the two digital port numbers:

void MeColorSensor::TurnOnLight(void)
{
  MePort::dWrite1(1);
}

void MeColorSensor::TurnOnmodule(void)
{
  MePort::dWrite2(0);//power on
}

This is confirmed by a rotated product image, giving:

  • blue: Two digital ports.
  • white: I2C Port.
  • S1 = led off (from code and image)
  • S2 = sensor off (from code and image)

The Adafruit sensor uses SDA and SCL to communicate with the sensor. There is also a LED, which can be turned on and off. Mapping the 7 sensor pins to the Makeblock connector gives:

  1. LED = LED off, S1 (black, 5)
  2. INT = sensor off, S2 (white, 6)
  3. SDA = SDA (yellow, 2)
  4. SCL = SCL (blue, 1)
  5. 3V3 = not used
  6. GND = GND (green, 3)
  7. VIN = VCC (red, 4)

None of the pins is at the right position. That is why I've used a RJ25 to dupont cable.

The following code works with an Auriga. It uses the Adafruit library (modified Adafruit example):

#include <Wire.h>
#include "Adafruit_TCS34725.h"

Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_50MS, TCS34725_GAIN_4X);

void setup() {
  Serial.begin(9600);
  tcs.begin();
}

void loop() {
  uint16_t clear, red, green, blue;

  tcs.setInterrupt(false);
  delay(60); 
  tcs.getRawData(&red, &green, &blue, &clear);
  tcs.setInterrupt(true);
  
  Serial.print("C:\t"); Serial.print(clear);
  Serial.print("\tR:\t"); Serial.print(red);
  Serial.print("\tG:\t"); Serial.print(green);
  Serial.print("\tB:\t"); Serial.print(blue);
  Serial.println();

  delay (5000);
}

Unfortunately the Makeblock library example doesn't work with this Adafruit module.

Comparing the header files from both drivers (Makeblock and Adafruit) shows different device ID's: The makeblock driver uses a MANUFACTURER_ID (0X92) and the Adafruit uses the value for TCS34725_ID (0x12).

The Adafruit code works, but the Makeblock drivers can't be used with this Adafruit board. This means that this Adafruit sensor can not be used with scratch. It only works using the Adafruit libraries.


Step 30: Make It Move

After all sensors and LEDs it's time for motors. There are 3 types of Makeblock motors: Steppers, Servos and DC motors. This Instructable will be limited to DC-motors.

The Auriga and mCore boards each contain two motor ports. And the motor speed is controlled by PWM. This signal is made by the microcontroller. And allows the microcontroller to perform other things while driving. Such as checking the distance to an object.

There are 2 ways to control the motors:

  1. Use the Makeblock library.
  2. Use the arduino pin library.

The makeblock library for the mCore robot is the easiest to use. There are classes to create a motor object, of which the speed can be set:

      MeDCMotor (void)
      MeDCMotor (uint8_t port)
void  setpin (uint8_t dir_pin, uint8_t pwm_pin)
void  reset (uint8_t port)
void  reset (uint8_t port, uint8_t slot)
void  run (int16_t speed)
void  stop (void)

The following sample code controls 2 motors, the buzzer, an ultrasonic sensor and the internal LEDs. The exampe is made for the mCore robot, and uses the Makeblock library.

#include "MeMCore.h"

#define LEDNUM  2
#define BUZZER_PORT 8

MeDCMotor motor1(9);
MeDCMotor motor2(10);

MeRGBLed led(PORT_7, LEDNUM); 
MeUltrasonicSensor ultraSensor(PORT_3); 
MeBuzzer buzzer;

int distanceMax = 50;    
int distanceNow;    

int speed1=120; // full
int speed2= 90; // half
int speed3= 60; // turn
int speed4=  0; // stop

void setup()
{
  led.setColor (128,128,128);
  led.show(); 

  buzzer.setpin(BUZZER_PORT);
  buzzer.noTone();

  delay (1000);
}

void loop()
{
   distanceNow = ultraSensor.distanceCm();
   if (distanceNow > distanceMax * 3)
   {  // blue
      led.setColor (0, max (distanceNow , 255), max (distanceNow , 255));
      led.show();
      motor1.run(+speed1);       
      motor2.run(-speed1);
   }
   else if (distanceNow > distanceMax)
   {  // red
      led.setColor (max (400 - distanceNow , 255), 0, 0);
      led.show();
      motor1.run(+speed2);       
      motor2.run(-speed2);
   }
   else
   {  
      // Stop
      led.setColor (127,255, 0);
      led.show();
      motor1.run(speed4);      // motor1.stop(); 
      motor2.run(speed4);      // motor2.stop();
      buzzer.tone(587, 250);   // NOTE_D5
      buzzer.tone(659, 250);   // NOTE_E5
      buzzer.tone(523, 250);   // NOTE_C5
      
      do 
      {   
         motor1.run(-speed3); // Reverse      
         motor2.run(-speed3); 
         delay(300);  
      }  while (ultraSensor.distanceCm() < distanceMax * 2);
   }
   delay(100);  
}

This software isn't best way to avoid objects, the robot only turns to the right.

The following 4 code examples do the same as the previous example. There are 2 programs for the mCore and 2 programs for the Auriga. Each board has a direct Arduino pin PWM example and an example which uses the Makeblock library.

Step 31: Led Matrix 8 X 16

This is, what I think, the best addition for the mbot robot. The screen is easy to control with Skratch, but there are also many functions in the library. For example, the following short example gives a news ticker:

#include "MeMCore.h"

MeLEDMatrix ledMx(PORT_2);

void setup()
{
  ledMx.setBrightness(8);
  ledMx.setColorIndex(1);
}

void loop()
{
  for (int i=50; i>-30; i--)
  {
    ledMx.drawStr(i,8,"hello ");
    delay (20);
  }
}

Step 32: DIY Robot

As a final step, I've made this robot. It is an mCore robot, with two DIY NeoPixel elements. The software is the almost same as the motor example with the ultrasonic sensor. The eyes use the code from the Auriga Extension module. And the 8x16 LED displays uses a modified news-ticker (from the previous step).

With the help of these three code examples, it should be possible to make a similar robot.


GosseAdema

Make It Move Contest 2017

Runner Up in the
Make It Move Contest 2017