Visual Studio Ide for Arduino
https://www.visualmicro.com/forums/YaBB.pl
Other >> Arduino for Visual Studio 2010 >> Arduino Micro/Leonardo + FreeRTOS
https://www.visualmicro.com/forums/YaBB.pl?num=1435870033

Message started by AviatorLeo on Jul 2nd, 2015 at 9:47pm

Title: Arduino Micro/Leonardo + FreeRTOS
Post by AviatorLeo on Jul 2nd, 2015 at 9:47pm
Hello,

As you already may know Arduino Micro/Leonardo has a 32u4 microcontroller. This allows native USB communication, but also handles serial communication different from boards based on 328 microcontroller.

I'm using FreeRTOS for my project and everything was working fine on my Arduino Uno, but now that I changed to the Arduino Micro (for miniaturizing and Nano was not available at the time of the purchase) serial communication works erratically. My program does not work unless I have serial communication opened, and I need it to work weather I have serial port opened or not, just like in the Uno. This problem is while using Arduino IDE or Matlab (I want Matlab communication). Strangely, using VisualMicro works just fine. What I have noticed is that the queue I'm using in the RTOS gets flooded when serial is not opened and messes with the  execution of the OS. Is there a way to fix this without changing microcontroller?

Second. I'm trying to use a Bluetooth LE nRF8001 from Adafruit and when initializing the device my RTOS doesn't start correctly. Any clues?

Thanks    :)

The code


//-- Libraries --
#include "FreeRTOS_AVR.h"
#include "basic_io_avr.h"
#include <SPI.h>
#include <Wire.h>
#include <Stepper.h>
#include <assert.h>
#include "Adafruit_BLE_UART.h"

//-- Declarations --
//Motor
int motorSpeed = 150; //Speed in RPM
const int stepsPerRevolution = 200;//Number of steps per revolution of the motor

//Sensors' Pins
int flex1 = 0; //Sensor 1 pin 0 analog
int flex2 = 1;
int flex3 = 2;
int flex4 = 3;
int flex5 = 4;
int flex6 = 5;
int flex7 = 6;
int flex8 = 7;

//Bluetooth
#define ADAFRUITBLE_REQ 2
#define ADAFRUITBLE_RDY 0
#define ADAFRUITBLE_RST 1

Adafruit_BLE_UART uart = Adafruit_BLE_UART(ADAFRUITBLE_REQ, ADAFRUITBLE_RDY, ADAFRUITBLE_RST); //This is the line that messes with the RTOS

//Motor Def

Stepper myStepper(stepsPerRevolution, 7, 8, 10, 11); //Define the steps per revolution and the pins

//Others
uint32_t temps = 0; //Time stamp for Matlab. Just declared once

//RTOS Task definition
void vMotorTask(void *pvParameters);
void vSensorTask(void *pvParameters);
void vMatlabTask(void *pvParameters);
void vBLETask(void *parameters);

//Tests for RTOS
const char *pcTextForMotorTask = "MotorTask\r\n";
const char *pcTextForSensorTask = "Sensor Task\r\n";
const char *pcTextForMatlabTask = "MatlabTask\r\n";
const char *pcTextForBLETask = "BLE\r\n";

//-- Handler Init --
xQueueHandle xQueue1;

/*********/
This function is called whenever select ACI events happen
/********/
void aciCallback(aci_evt_opcode_t event)
{
     switch (event)
     {
     case ACI_EVT_DEVICE_STARTED:
           Serial.println(F("Advertising started"));
           break;
     case ACI_EVT_CONNECTED:
           Serial.println(F("Connected!"));
           break;
     case ACI_EVT_DISCONNECTED:
           Serial.println(F("Disconnected or advertising timed out"));
           break;
     default:
           break;
     }
}

//-- Initialization --
void setup()
{
     //MatLab
     assert(sizeof(uint32_t) == sizeof(unsigned long)); //change the length of the data to be transmitted to Matlab

     //Serial Communication
     Serial.begin(9600); //transmission speed in bits per seconds
     while (!Serial);

     //Bluetooth
     //uart.setACIcallback(aciCallback);
     //uart.setDeviceName("AIS_PRO"); /* 7 characters max! */
     //uart.begin();

     //Queue
     xQueue1 = xQueueCreate(64, sizeof(float));

     //Motor
     myStepper.setSpeed(motorSpeed);
     pinMode(3, OUTPUT);
     pinMode(5, OUTPUT);

     //Sensors
     pinMode(flex1, INPUT); //Declare sensor pins as inputs. Declare as many as needed
     pinMode(flex2, INPUT);
     pinMode(flex3, INPUT);
     pinMode(flex4, INPUT);
     pinMode(flex5, INPUT);
     pinMode(flex6, INPUT);
     pinMode(flex7, INPUT);
     pinMode(flex8, INPUT);

     //RTOS Task Creation
     if (xQueue1 != NULL)
     {
           xTaskCreate(vMotorTask, (signed char*) "Motor", 200, (void*)pcTextForMotorTask, 2, NULL);
           xTaskCreate(vSensorTask, (signed char*) "Sensor Read", 300, (void*)pcTextForSensorTask, 2, NULL);
           xTaskCreate(vMatlabTask, (signed char*) "Matlab Read", 300, (void*)pcTextForMatlabTask, 2, NULL);
           //xTaskCreate(vBLETask, (signed char*) "BLE", 300, (void*)pcTextForBLETask, 2, NULL);

           vTaskStartScheduler(); //Starts the scheduler task
     }

     for (;;); //Infinite loop
     // return 0;
}

//-- Tasks --
void BoucleMoteur() //function that will be used in the loop
{
     myStepper.step(1660);
     myStepper.step(-1660);
}


void vMotorTask(void *pvParameters)
{
     char *pcTaskName;

     pcTaskName = (char*)pvParameters;

     digitalWrite(3, HIGH);
     digitalWrite(5, HIGH);

     for (;;)
     {
           if (!Serial)
           {
                 vPrintString(pcTaskName);
                 BoucleMoteur(); //make the motor work!
                 vPrintString("Motor Running\r\n");
           }

           else
           {
                 vPrintString(pcTaskName);
                 BoucleMoteur(); //make the motor work!
                 vPrintString("Motor Running\r\n");
           }
     }
}

void vSensorTask(void *pvParameters)
{
     portTickType xLastWakeTime;
     char *pcTaskName;
     float Sensor1, Sensor2, Sensor3, Sensor4, Sensor5, Sensor6;
     portBASE_TYPE xStatus;

     xLastWakeTime = xTaskGetTickCount();
     pcTaskName = (char*)pvParameters;

     for (;;)
     {

           if (!Serial)
           {
                 vPrintString(pcTaskName);

                 Sensor1 = analogRead(flex1);//Sensor Read
                 Sensor2 = analogRead(flex2);
                 Sensor3 = analogRead(flex3);
                 Sensor4 = analogRead(flex4);
                 Sensor5 = analogRead(flex5);
                 Sensor6 = analogRead(flex6);

                 vTaskDelayUntil(&xLastWakeTime, (200 / portTICK_RATE_MS));
           }

           else
           {
                 vPrintString(pcTaskName);

                 Sensor1 = analogRead(flex1);//Sensor Read
                 Sensor2 = analogRead(flex2);
                 Sensor3 = analogRead(flex3);
                 Sensor4 = analogRead(flex4);
                 Sensor5 = analogRead(flex5);
                 Sensor6 = analogRead(flex6);

                 xStatus = xQueueSendToBack(xQueue1, &Sensor1, 0);
                 xStatus = xQueueSendToBack(xQueue1, &Sensor2, 0);
                 xStatus = xQueueSendToBack(xQueue1, &Sensor3, 0);
                 xStatus = xQueueSendToBack(xQueue1, &Sensor4, 0);
                 xStatus = xQueueSendToBack(xQueue1, &Sensor5, 0);
                 xStatus = xQueueSendToBack(xQueue1, &Sensor6, 0);

                 if (xStatus != pdPASS)
                 {
                       /* We could not write to the queue because it was full, this must
                       be an error as the queue should never contain more than one item! */
                       vPrintString("Could not send to the queue.\r\n");
                 }

                 vTaskDelayUntil(&xLastWakeTime, (200 / portTICK_RATE_MS));
           }
     }
}

void vMatlabTask(void *pvParameters)
{
     float RS1, RS2, RS3, RS4, RS5, RS6;
     portBASE_TYPE xStatus;
     const portTickType xTicksToWait = 300 / portTICK_RATE_MS;

     char *pcTaskName;
     pcTaskName = (char*)pvParameters;

     for (;;)
     {
           if (!Serial)
           {
                 vPrintString(pcTaskName);
           }

           else
           {
                 vPrintString(pcTaskName);

                 if (uxQueueMessagesWaiting(xQueue1) != 0)
                 {
                       vPrintString("Queue should have been empty!\r\n");
                 }

                 xStatus = xQueueReceive(xQueue1, &RS1, xTicksToWait);
                 xStatus = xQueueReceive(xQueue1, &RS2, xTicksToWait);
                 xStatus = xQueueReceive(xQueue1, &RS3, xTicksToWait);
                 xStatus = xQueueReceive(xQueue1, &RS4, xTicksToWait);
                 xStatus = xQueueReceive(xQueue1, &RS5, xTicksToWait);
                 xStatus = xQueueReceive(xQueue1, &RS6, xTicksToWait);
if (xStatus == pdPASS)
                 {
                       vPrintStringAndNumber("Received 1= ", RS1);
                       vPrintStringAndNumber("Received 2= ", RS2);
                       vPrintStringAndNumber("Received 3= ", RS3);
                       vPrintStringAndNumber("Received 4= ", RS4);
                       vPrintStringAndNumber("Received 5= ", RS5);
                       vPrintStringAndNumber("Received 6= ", RS6);
                 }
                 else
                 {
                       vPrintString("Could not receive from the queue.\r\n");
                 }


                 temps = millis();
                 Serial.write('z'); //send the character z through the serial (it's the signal that starts Matlab program)
                 Serial.write((uint8_t*)&temps, sizeof(temps)); //sends the time with the right format
                 Serial.write((uint8_t*)&RS1, sizeof(uint16_t)); //sends the sensor data with the right format
                 Serial.write((uint8_t*)&RS2, sizeof(uint16_t));
                 Serial.write((uint8_t*)&RS3, sizeof(uint16_t));
                 Serial.write((uint8_t*)&RS4, sizeof(uint16_t));
                 Serial.write((uint8_t*)&RS5, sizeof(uint16_t));
                 Serial.write((uint8_t*)&RS6, sizeof(uint16_t));
}
     }
}

void loop(){}

Title: Re: Arduino Micro/Leonardo + FreeRTOS
Post by Visual Micro on Jul 2nd, 2015 at 10:35pm
Hi,

1)

Try replacing while(!Serial) with delay(2000)

2)

I don't know the micro very well or the BT board but I looked at the examples for the BT board and the definition of the arguments of the call you are making.

However if ADAFRUITBLE_REQ, ADAFRUITBLE_RDY, ADAFRUITBLE_RST are pin numbers I can tell you that 0 and 1 are the HardwareSerial pins.

This is the default from the library examples on git:-

// Connect CLK/MISO/MOSI to hardware SPI
// e.g. On UNO & compatible: CLK = 13, MISO = 12, MOSI = 11
#define ADAFRUITBLE_REQ 10
#define ADAFRUITBLE_RDY 2     // This should be an interrupt pin, on Uno thats #2 or #3
#define ADAFRUITBLE_RST 9

Does the micro have an alternative spare interrupt pin for ADAFRUITBLE_RDY?


Title: Re: Arduino Micro/Leonardo + FreeRTOS
Post by AviatorLeo on Jul 3rd, 2015 at 3:24pm
Hi,

1)

I replaced the while(!Serial) and now it kind of works. At least is now starts my motor. Thanks =D

2)

Yes, Arduino Micro actually has 5 interrupt pins. Nevertheless I have every pin occupied with other tasks.
Also, on the tutorial of Adafruit for the BT board (https://learn.adafruit.com/getting-started-with-the-nrf8001-bluefruit-le-breakout/hooking-everything-up) it said that those pins could be changed, so it is not a problem I used other pins. The RDY had to be an interrupt pin and the Arduino Micro has int0 (pin 3), int1 (pin 2), int2 (pin 0), int3 (pin 1), int4 (pin 7).

Title: Re: Arduino Micro/Leonardo + FreeRTOS
Post by Visual Micro on Jul 3rd, 2015 at 3:27pm
Yes you can not use pins 0 and 1 if you also want to use Serial so sounds like you have run out of pins.

Are you using all the analog pins? They can be used as digital.

Title: Re: Arduino Micro/Leonardo + FreeRTOS
Post by AviatorLeo on Jul 3rd, 2015 at 3:29pm
Yes I am using all my analog pins analog pins. And because of the board pin layout, some Digital Pins double as analog, which I am using too.

And the Serial I am using is through the USB port, does it matter?

Title: Re: Arduino Micro/Leonardo + FreeRTOS
Post by Visual Micro on Jul 3rd, 2015 at 3:33pm
Unfortunately the usb is connected to pin 0 and 1

Title: Re: Arduino Micro/Leonardo + FreeRTOS
Post by AviatorLeo on Jul 3rd, 2015 at 3:40pm
Thanks :)

Ok, that USB connection is actually going to disappear. That is the reason for the BT breakout board, and that BT board communicates with the Arduino via SPI. Will it matter then? Because then my problem is again that the BT code crashes the program.

Title: Re: Arduino Micro/Leonardo + FreeRTOS
Post by Visual Micro on Jul 3rd, 2015 at 3:48pm
I'm not sure. I suspect that if you have not used Serial.begin() you might be okay. You can try it by commenting the serial code.

Visual Studio Ide for Arduino » Powered by YaBB 2.5.2!
YaBB Forum Software © 2000-2019. All Rights Reserved.