Friday, 26 May 2017

Foireann Visage (Face Team) Arduino RTOS with Nextion Code

Included below is the full Arduino RTOS code that takes x coordinates & distance values serially from mbed and converts them to a form that the Nextion Display will understand.

The code consists of two threads. A receive thread and a transmit thread. Two global variables for x & distance are protected by Semaphores.


The first thread parse's in an integer from the buffer. Parse was used as it is much faster than using Serial.read.
The lines below are protected by a Semaphore.

ReceiveInt = Serial1.parseInt(); // read next valid integer from the serial buffer
      Serial.println("Parse Value");
      Serial.println(ReceiveInt);



The Second thread takes the "ReceiveInt" value and splits it into both x & distance. The comments on the code explains how the 2ReceiveInt" value is split up.

       temp = ReceiveInt;
       temp2 = temp;
                     // value read in is id + x coordinate e.g 4 + 121 = 4121
            x_coord = temp2%1000;  // x coordinate always 3 digits, mod 1000 gives the remainder 3                                                                digits from temp e.g. 4121%1000 = 121
            temp2 -= x_coord;            // subtract 3 digital val so only 4th digit is left, e.g. 4121 - 121 =                                                                4000
            x_coord -=100;                 // subtract 100 offset added to xval 121 - 100 = 21... 21 origional x                                                            val
            id_val = temp2/1000;         // Divide by 1000 to get id val e.g = 4000/1000 = 4



The next few lines of code converts the x value into a float so it can be accurately divided and re-scaled so the min & max of the vision team corresponds to the min & max on the Nextion.


            x_val = 0;
            x_val = x_coord;
            x_val_f = 0;
            x_val_f = x_val;
            //Serial.println(x_val_f);
            x_val_f -= 25;
            //Serial.println(x_val_f);
            x_val_f /= 125;
            //Serial.println(x_val_f);
            x_val_f *= 400;
            //Serial.println(x_val_f);
            x_val = x_val_f;
            //Serial.println(x_val);



The next few lines cause our local copy of x to track the value of x sent down by the vision  team. This will cause our x value to slowly move to where it s supposed to be instead of jumping from a to b.

            if(x_out < x_val)
              x_out += a;
         
            if(x_out > x_val)
              x_out -= a;


The next few lines build's the message that will be sent to the Nextion display. Commands are sent to the Nextion Display using a serial string. The format of the string has to be in the following form; "pic x,y,id".

String concatenate (srtcat) had to be used over simple string addition (string_out = string1 + string2) due to some unknown issue with the Arduino freeRTOS not liking strings.

the "itoa" command represents integer to ASCII.




            strcpy(TxMessage,pic);       //"pic "          
            itoa(x_val, x_char, 10);          
            strcat(TxMessage, x_char);  //"pic x"

            strcat(TxMessage, y);          //"pic x,y,"  
   
           itoa(id_val, id_char, 10);

           strcat(TxMessage, id_char);  //"pic x,y,id"


This final string is then sent to the Nextion using the following command
       myNextion.sendCommand(TxMessage);



Below is the full Arduino code


#include
#include  // add the FreeRTOS functions for Semaphores (or Flags).
#include
#include
#include
SoftwareSerial nextion(2, 3);// Nextion TX to pin 2 and RX to pin 3 of Arduino
Nextion myNextion(nextion, 9600); //create a Nextion object named myNextion using the nextion serial port @ 9600bps

SemaphoreHandle_t xSemaphore;


// define two tasks for Receive & Transmit
void xRx( void *pvParameters );
void idTx( void *pvParameters );

int ReceiveInt = 0, x_coord, id_val, temp, tempold, temp2, bob, a = 5, x_val, x_out;
char pic[5] = "pic ", y[5] = ",15,",TxMessage[10],x_char[10], id_char[10];

// the setup function runs once when you press reset or power the board

void setup() {
  Serial.begin(9600);
  Serial.println("Hello world!");
  Serial1.begin(9600);
  myNextion.sendCommand("cls WHITE");
  myNextion.sendCommand("pic 200,15,10");
  if ( xSemaphore == NULL )  // Check to confirm that the Semaphore has not already been created.
  {
    xSemaphore = xSemaphoreCreateMutex();  // Create a mutex semaphore we will use to manage tasksh
    if ( ( xSemaphore ) != NULL )
      xSemaphoreGive( ( xSemaphore ) );  // Make the mutex available for use, by "Giving" the Semaphore.
  }

  // Now set up two tasks to run independently.
  xTaskCreate(
    xRx
    ,  (const portCHAR *)"Receive"   // A name just for humans
    ,  128  // Stack size
    ,  NULL
    ,  1  // priority
    ,  NULL );

  xTaskCreate(
    idTx
    ,  (const portCHAR *) "Transmit"
    ,  128 // This stack size can be checked & adjusted by reading Highwater
    ,  NULL
    ,  1  // priority
    ,  NULL );

  // Now the task scheduler, which takes over control of scheduling individual tasks, is automatically started.
}

void loop()
{

}

/*--------------------------------------------------*/
/*---------------------- Tasks ---------------------*/
/*--------------------------------------------------*/

void xRx(void *pvParameters)  // This is the Receive Task
{
  (void) pvParameters;


  for (;;) // A Task shall never return or exit.
  {
     if ( xSemaphoreTake( xSemaphore, ( TickType_t ) 5 ) == pdTRUE )
    {
     // Serial.println("Semaphhore 1 lock");
   //  if (Serial1.available()){
 
      ReceiveInt = Serial1.parseInt(); // read next valid integer from the serial buffer
      Serial.println("Parse Value");
      Serial.println(ReceiveInt);
   //  }
      Serial.println("Semaphhore 1 free");
      xSemaphoreGive( xSemaphore ); // Now free or "Give" to others
     
      vTaskDelay(50);  // one tick delay (15ms) in between reads for stability
    }
  }
}


void idTx(void *pvParameters)  // This is a task.
{
  (void) pvParameters;
  float x_val_f = 0.0;
  for (;;) // A Task shall never return or exit.
  {
    if ( xSemaphoreTake( xSemaphore, ( TickType_t ) 5 ) == pdTRUE )
      {
          //Serial.println("Semaphhore 2 lock");
          temp = ReceiveInt;
          xSemaphoreGive( xSemaphore ); // Now free or "Give" the Serial Port for others
          Serial.println(temp);
          if (temp >= 1000)
            {
             Serial.println(temp);      
            temp2 = temp;
                     // value read in is id + x coordinate e.g 4 + 121 = 4121
            x_coord = temp2%1000;  // x coordinate always 3 digits, mod 1000 gives the remainder 3 digits from temp e.g. 4121%1000 = 121
            temp2 -= x_coord;      // subtract 3 digital val so only 4th digit is left, e.g. 4121 - 121 = 4000
            x_coord -=100;        // subtract 100 offset added to xval 121 - 100 = 21... 21 origional x val
            id_val = temp2/1000;   // Divide by 1000 to get id val e.g = 4000/1000 = 4
            x_val = 0;
            x_val = x_coord;
            x_val_f = 0;
            x_val_f = x_val;
            //Serial.println(x_val_f);
            x_val_f -= 25;
            //Serial.println(x_val_f);
            x_val_f /= 125;
            //Serial.println(x_val_f);
            x_val_f *= 400;
            //Serial.println(x_val_f);
            x_val = x_val_f;
            //Serial.println(x_val);
            bob = id_val; //Fix for issue
            id_val = bob; //
           
           
            Serial.println(id_val);
            if(x_out < x_val)
              x_out += a;
         
            if(x_out > x_val)
              x_out -= a;
 

            strcpy(TxMessage,pic);      //"pic "          
            itoa(x_val, x_char, 10);          
            strcat(TxMessage, x_char);  //"pic x"

            strcat(TxMessage, y);       //"pic x,y,"  
   
           itoa(id_val, id_char, 10);

           strcat(TxMessage, id_char);      //"pic x,y,id"
           
            Serial.println(TxMessage);
            Serial.println("-----------------------------------------");
          }
          myNextion.sendCommand(TxMessage);
         
          vTaskDelay(50);  // one tick delay (15ms) in between reads for stability
      }
  }
}

3 comments:

  1. Thank you for your post.Hawkscode is a one of the best
    IT service provider

    ReplyDelete
  2. Thank you for your post. Hawkscode Uk is the leading IT service provider. Hawkscode Uk provides website design uk services.

    ReplyDelete
  3. Awesome Content written by the author.
    Kudos!!!!
    Read more about how to remove shortcut virus from your computer.
    Also see how to remove adware malware easily and completely.

    ReplyDelete