mCore: mapeo de puertos y programación

INTRODUCCIÓN

Como seguro ya sabéis la placa mCore de nuestro mBot es una placa basada en Arduino y por tanto podemos programarla sin problemas desde el propio IDE de Arduino como si fuera un Arduino UNO.


MakeBlock proporciona librerías que nos permiten interactuar de un modo sencillo con cada uno de los componentes que componen la placa (driver para los motores, buzzer, sensor de luz, LEDs RGB, etc) y también con los módulos adicionales (seguidor de líneas, sensor de sonido, sensor PIR, ultrasonidos ,etc).

Si instalamos las librerías de Arduino podemos ver ejemplos de utilización de cada una de ellas.

En este tutorial veremos cómo podemos programar nuestra placa mCore tanto con las librerías de Makeblock como sin ellas e incluso utilizando librerías de terceros.

La ventaja que tiene la placa mCore es que ya tenemos muchos componentes integrados dentro de la propia placa por el contrario esto hace que no tengamos disponibles todos los pines que podríamos tener en una placa Arduino UNO ya que han sido reservados para dichos componentes.

MAPEO DE PUERTOS

El mapeo de puertos, es decir, la relación entre un puerto y los pines asociados a éste lo podemos ver en la siguiente tabla:

Puerto Pines Arduino

SLOT 1, SLOT 2

PORT_1 D11, D12
PORT_2 D9, D10
PORT_3 A2, A3
PORT_4 A0, A1
PORT_6 D8, A6
PORT_7 A7, D13
PORT_8 D8, A6
PORT_9 D6, D7
PORT_10 D5, D4
M1 D6, D7
M2 D5, D4

El mapeo de puertos lo podemos ver si miramos el código del fichero MeMCore.h

/********************* Mbot Board GPIO Map *********************************/
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 },
};

Como podemos ver cada puerto consta de dos slots (slot 1 y slot 2) y cada slot corresponde a un pin de nuestro Arduino.

Entonces ¿Cómo acceder a estos pines? , bueno pues una manera sencilla sería utilizando la propia librería MePort tal y como se muestra a continuación:

#include <MeMCore.h>

MePort port(PORT_2);

int16_t slot1Pin = port.pin1(); // SLOT 1 del puerto 2
int16_t slot2Pin = port.pin2(); // SLOT 2 del puerto 2

Por tanto en la variable slot1Pin tendremos el pin D9 y en la variable slot2Pin tendremos el pin D10 de nuestra placa mCore puesto que hemos especificado (en este caso) el puerto 2 (PORT_2).

Por supuesto también podemos poner directamente el pin que queremos utilizar sin usar la librería:

int16_t slot1Pin = 9;
int16_t slot2Pin = 10;

Como hemos comentado anteriormente en la placa mCore ya tenemos muchos componentes integrados y en la siguiente tabla podemos ver los pines asociados a estos componentes:

Componente Pin asociado
Sensor de luz A6
Buzzer D8
Pulsador A7
LEDS RGB D13
Motor 1 D6, D7
Motor 2 D4, D5
Emisor de infrarrojos D3
Receptor de infrarrojos D2

Esto lo podemos ver en el esquema de la placa mCore que nos proporciona Makeblock:

Realizada esta introducción voy a poner algunos ejemplos de código programado desde el IDE de Arduino donde podemos ver cómo se interactúa con los distintos componentes mediante la utilización de la propias librerías de Makeblock, sin ellas e incluso con librerías de terceros.

COMPONENTES INTEGRADOS EN LA PLACA

Aquí podemos ver los diferentes componentes de la placa mCore:

Vamos con los ejemplos:

BUZZER

Ejemplo sin utilizar la librería de Makeblock:

NOTA: En este caso utilizaremos la librería NewTone.

// Notas
#include "pitches.h"

#include <NewTone.h>

const int pinBUZZER = 8; 

const int melodia_notas[7] = {NOTE_F5, NOTE_FS5, NOTE_G5, NOTE_GS5, 0, NOTE_F5, NOTE_GS5};
const int melodia_total_notas = 7;
const int melodia_duracion[] = {8, 8, 8, 8, 8, 8, 2}; 

  
void setup()
{
  pinMode(pinBUZZER, OUTPUT); 
}
 
void loop()
{
  melodia(melodia_notas,melodia_duracion,melodia_total_notas);
}

void melodia(const int notas_melodia[], const int duracion_notas[], const int total_notas)
{ 
  for (int nota = 0; nota < total_notas; nota++) 
  {
    int duracionNota = 1000 / duracion_notas[nota];
    NewTone(pinBUZZER, notas_melodia[nota], duracionNota);
    int pausaEntreNotas = duracionNota * 1.30;   
    delay(pausaEntreNotas);
    noNewTone(pinBUZZER);
  }
}

Ejemplo utilizando la librería de Makeblock:

// Notas
#include "pitches.h"

#include <MeMCore.h>

const int melodia_notas[7] = {NOTE_F5, NOTE_FS5, NOTE_G5, NOTE_GS5, 0, NOTE_F5, NOTE_GS5};
const int melodia_total_notas = 7;
const int melodia_duracion[] = {8, 8, 8, 8, 8, 8, 2}; 

double factor_delay=0.3;

MeBuzzer buzzer;
  
void setup()
{
}
 
void loop()
{
  melodia(melodia_notas,melodia_duracion,melodia_total_notas);
}

void melodia(const int notas_melodia[], const int duracion_notas[], const int total_notas)
{ 
  for (int nota = 0; nota < total_notas; nota++) 
  {
    int duracionNota = 1000 / duracion_notas[nota];
    buzzer.tone(notas_melodia[nota], duracionNota);

    /*
      La función  "buzzer.tone" ya introduce el delay de la duración de la nota a diferencia de la librería "tone" --> con lo cual solo hay que añaidr el 30% 
      ojo! que si la nota es 0 no se introduce el delay de la duración de la nota y solo en este caso si que hay que añadir la duración de la nota + 30% en el delay

     */
    factor_delay=0.3; 
    if (notas_melodia[nota] == 0)
      factor_delay=1.3;
  
    int pausaEntreNotas = duracionNota * factor_delay;   
    delay(pausaEntreNotas);
    buzzer.noTone();
  }
}

DRIVER MOTORES DC

NOTA: Si miramos el esquema de la placa vemos que para controlar los motores se utiliza el chip TB6612.

Ejemplo sin utilizar la librería de Makeblock:

/* 
 * OBSERVACION:
 * 
 * pinAIN1 y pinAIN2  utilizan el mismo Pin de tal manera que cuando uno está a HIGH el otro estará a LOW
 * Los mismo para pinBIN1 y pinBIN2 
 * El Pin stantbye ya se encuentra a +5V y por tanto en HIGH.
 * 
 */
const int pinPWMA = 6;
const int pinAIN1_AIN2 = 7; 
const int pinPWMB = 5;
const int pinBIN1_BIN2 = 4;
  
void setup()
{
   pinMode(pinPWMA, OUTPUT);
   pinMode(pinAIN1_AIN2, OUTPUT);

   pinMode(pinPWMB, OUTPUT);
   pinMode(pinBIN1_BIN2, OUTPUT);
}
 
void loop()
{

  Avance(255);
  delay(2000);
  Retroceso(255);
  delay(2000);
  Izquierda(255);
  delay(2000);
  Derecha(255);
  delay(2000);
  Parar();
  delay(2000);

}

void Avance(int velocidad)
{
  analogWrite(pinPWMA, velocidad); 
  digitalWrite(pinAIN1_AIN2, LOW);

  analogWrite(pinPWMB, velocidad); 
  digitalWrite(pinBIN1_BIN2, HIGH);
}

void Retroceso(int velocidad)
{
   analogWrite(pinPWMA, velocidad); 
  digitalWrite(pinAIN1_AIN2, HIGH);

  analogWrite(pinPWMB, velocidad); 
  digitalWrite(pinBIN1_BIN2, LOW);
}
 
void Izquierda(int velocidad)
{
  analogWrite(pinPWMA, velocidad); 
  digitalWrite(pinAIN1_AIN2, HIGH);

  analogWrite(pinPWMB, velocidad); 
  digitalWrite(pinBIN1_BIN2, HIGH);
}
 
void Derecha(int velocidad)
{
  analogWrite(pinPWMA, velocidad); 
  digitalWrite(pinAIN1_AIN2, LOW);

  analogWrite(pinPWMB, velocidad); 
  digitalWrite(pinBIN1_BIN2, LOW);
}

void Parar()
{ 
  analogWrite(pinPWMA, 0); 
  digitalWrite(pinAIN1_AIN2, HIGH);

  analogWrite(pinPWMB, 0); 
  digitalWrite(pinBIN1_BIN2, HIGH);
}

Ejemplo utilizando la librería de Makeblock:

Vemos en el ejemplo que podemos utilizar dos librerías: MeDCMotor y MBotDCMotor. La ventaja de la primera librería respecto a la segunda es que podemos especificar distintas velocidades para cada motor por el contrario con la segunda librería la velocidad especificada se aplicará a los dos motores pero tiene la ventaja que nos simplifica el escribir más código ya que con una sola línea podemos programar las instrucciones.

#include <MeMCore.h>

//****************************
// METODO 1
//****************************
MeDCMotor motor1(M1);
MeDCMotor motor2(M2);

//****************************
// METODO 2
//****************************
MBotDCMotor motor(M1);

void setup()
{
}

void loop()
{

  //****************************
  // METODO 1
  //****************************
  
  // El valor puede estar entre -255 y 255

  // Avanzar
  motor1.run(-255);
  motor2.run(255);
  delay(2000);

  // Retroceder
  motor1.run(255);
  motor2.run(-255);
  delay(2000);

  //Izquierda
  motor1.run(255);
  motor2.run(255);
  delay(2000);

  //Derecha
  motor1.run(-255);
  motor2.run(-255);
  delay(2000);
  
  // Parar
  motor1.stop();
  motor2.stop();
  delay(2000);

  //****************************
  // METODO 2
  //****************************

  // Avanzar
  motor.move(1,255);
  delay(2000);
  
  // Retroceder
  motor.move(2,255);
  delay(2000);

  // Izquierda
  motor.move(3,255);
  delay(2000);

  // Derecha
  motor.move(4,255);
  delay(2000);

  // Parar
  motor.move(1,0);
  delay(3000);
  
}

RGB LED

Ejemplo sin utilizar la librería de Makeblock:

NOTA: En este caso utilizaremos la librería NeoPixel de Adafruit.

#include <Adafruit_NeoPixel.h>

const int pinLEDS=13;
const int NUMLEDS=2;

int led1 = 0;
int led2 = 1;

Adafruit_NeoPixel led = Adafruit_NeoPixel(NUMLEDS, pinLEDS, NEO_GRB + NEO_KHZ800);

void setup() {

  led.begin(); 
}

void loop() {

  led.setPixelColor(led1, led.Color(255,0,0)); 
  led.setPixelColor(led2, led.Color(0,0,255)); 

  if (led1 == 0)
  {
    led1=1;
    led2=0;
  }
  else
  {
    led1=0;
    led2=1;
  }
    
  led.show();
  delay(500);

}

Ejemplo utilizando la librería de Makeblock:

#include <MeMCore.h>

MeRGBLed led(PORT_7,2);

int led1 = 1;
int led2 = 2;

void setup()
{
}

void loop() {

  led.setColor(led1, 255, 0, 0); 
  led.setColor(led2, 0, 0, 255); 

  if (led1 == 1)
  {
    led1=2;
    led2=1;
  }
  else
  {
    led1=1;
    led2=2;
  }
    
  led.show();
  delay(500);

}

SENSOR DE LUZ

Ejemplo sin utilizar la librería de Makeblock:

int sensorPin = A6; 

void setup() {
  
    Serial.begin(9600);
    pinMode(sensorPin, INPUT);
}

void loop() {

  unsigned int valorSensor = analogRead(sensorPin);
  Serial.print("luminosidad= ");
  Serial.println(valorSensor);
  delay(100);

}

Ejemplo utilizando la librería de Makeblock:

#include <MeMCore.h>

MeLightSensor sensorLuz(PORT_6);

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

void loop()
{
  unsigned int valorSensor = sensorLuz.read();
  Serial.print("lumionosidad= ");
  Serial.println(valorSensor);
  delay(100);
}

MÓDULOS ADICIONALES

SEGUIDOR DE LINEAS

Ejemplo sin utilizar la librería de Makeblock:

const int pinIzquierdo = 10;
const int pinDerecha = 9;

void setup()
{
  Serial.begin(9600);
  pinMode(pinIzquierdo, INPUT); 
  pinMode(pinDerecha, INPUT); 
}

void loop()
{
    int lecturaSensorIzquierdo= digitalRead(pinIzquierdo);
    int lecturaSensorDerecho= digitalRead(pinDerecha);
    
    if (lecturaSensorIzquierdo == LOW && lecturaSensorDerecho == LOW)
      Serial.println("Ambos sensores dentro de la linea"); 
    else if (lecturaSensorIzquierdo == LOW && lecturaSensorDerecho == HIGH)
      Serial.println("Sensor izquierdo fuera de la linea");
    else if (lecturaSensorIzquierdo == HIGH && lecturaSensorDerecho == LOW)
        Serial.println("Sensor derecho fuera de la linea");
    else if (lecturaSensorIzquierdo == HIGH && lecturaSensorDerecho == HIGH)
       Serial.println("Ambos sensores fuera de la linea"); 
      
    delay(200);
}

Ejemplo utilizando la librería de Makeblock:

#include <MeMCore.h>

MeLineFollower seguidorLineas(PORT_2);

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

void loop()
{
  int valorSensor = seguidorLineas.readSensors();
  switch(valorSensor)
  {
    case S1_IN_S2_IN:  Serial.println("Sensor izquierdo y derecho dentro de la lína negra"); break;
    case S1_IN_S2_OUT: Serial.println("Sensor derecho fuera de la linea negra"); break;
    case S1_OUT_S2_IN: Serial.println("Sensor izquierdo fuera de la linea negra"); break;
    case S1_OUT_S2_OUT:Serial.println("Sensor izquierdo y derecho fuera de la lína negra"); break;
    default: break;
  }
  delay(200);
}

SENSOR PIR

Ejemplo sin utilizar la librería de Makeblock:

const int pinPIR = 12;
const int pinModePIR = 11;

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

  
  /*
     MODO:
     LOW:  non-repeatable trigger
     HIGH: repeatable trigger

     IMPORTANTE: si se quiere poner en modo repeatable trigger comentar las dos lineas siguientes, es decir, no poner nada, ya que por defecto esta en este
     modo. Si se pone a HIGH o incluso se pone el pinMode(pinModePIR, OUTPUT); el sensor no funcionará correctamente.
  */
  
  //pinMode(pinModePIR, OUTPUT); 
  //digitalWrite(pinModePIR, LOW); 
  
}

void loop()
{
  
  int lecturaPIR= digitalRead(pinPIR);
  
  if(lecturaPIR == HIGH)
    Serial.println("Persona detectada");
  else
    Serial.println("");
  
  delay(20);
}

Ejemplo utilizando la librería de Makeblock:

#include <MeMCore.h>

MePIRMotionSensor myPIRsensor(PORT_1);

void setup()
{
  Serial.begin(9600);
 
  /*
     MODO:
     0:  non-repeatable trigger
     1: repeatable trigger

     IMPORTANTE: si se quiere poner en modo repeatable trigger no poner nada, ya que por defecto esta en este
     modo. Si se pone  myPIRsensor.SetPirMotionMode(1); el sensor no funcionará correctamente.
  
  */
  //myPIRsensor.SetPirMotionMode(0);   
}

void loop()
{
  if(myPIRsensor.isHumanDetected() )
    Serial.println("Persona detectada");
  else
    Serial.println("");
  
  delay(20);
}

SENSOR DE SONIDO

Ejemplo sin utilizar la librería de Makeblock:

int sensorPin = A1; 

void setup() {

  Serial.begin(9600);
  pinMode(sensorPin, INPUT);
    
}

void loop() {

  unsigned int valorSensor = analogRead(sensorPin);
  Serial.print("sonido= ");
  Serial.println(valorSensor);
  delay(100);
  
}

Ejemplo utilizando la librería de Makeblock:

#include <MeMCore.h>

MeSoundSensor sonido(PORT_4);

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

void loop()
{
  unsigned int valorSensor = sonido.strength();
  Serial.print("sonido= ");
  Serial.println(valorSensor);
  delay(100);
}

ADAPTADOR RJ25

NOTA: En los siguientes ejemplos supondremos que tenemos conectado un servomotor al slot 1 del adaptador RJ25.

Ejemplo sin utilizar la librería de Makeblock:

#include <Servo.h>

int16_t servoPin = 9;

Servo servo; 

void setup() 
{ 
  servo.attach(servoPin);  
} 

void loop() 
{ 
  servo.write(0);                 
  delay(2000);                          
  servo.write(180);
  delay(2000); 
}

Ejemplo utilizando la librería de Makeblock:

#include <MeMCore.h>

MePort port(PORT_2);

int16_t slot1Pin =  port.pin1();  // SLOT 1 del puerto
int16_t slot2Pin =  port.pin2();  // SLOT 2 del puerto

Servo servo; 

void setup() 
{ 
  servo.attach(slot1Pin);  
} 

void loop() 
{ 
  servo.write(0);                 
  delay(2000);                          
  servo.write(180);
  delay(2000); 
}

SENSOR DE ULTRASONIDOS

Ejemplo sin utilizar la librería de Makeblock:

NOTA: En este caso utilizaremos la librería NewPing.

#include <NewPing.h>

const int pinTRIGGER =  12; 
const int pinECHO =  12 ; 
const int MAX_DISTANCIA = 200;
  
NewPing sonar(pinTRIGGER, pinECHO, MAX_DISTANCIA);
  
void setup() {
  
  Serial.begin(9600);  
}

void loop() {
  
  delay(50);                      
  unsigned int distancia_medida = sonar.ping_cm();
  Serial.print("Distancia: ");
  Serial.print(distancia_medida); 
  Serial.println("cm");
}

Ejemplo utilizando la librería de Makeblock:

#include <MeMCore.h>

MeUltrasonicSensor sonar(PORT_1); 
  
void setup() {
  
  Serial.begin(9600); 
}

void loop() {
  
  delay(50);                      
  unsigned int distancia_medida= sonar.distanceCm();
  Serial.print("Distancia: ");
  Serial.print(distancia_medida); 
  Serial.println("cm");
}

 

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *