5 years, 6 months ago.

Arduino to Mbed SPI program code

Hi, I'am very new on Mbed. I would like to convert this arduino program to Mbed but I don't know how. This program is for reading an absolute encoder from CUI by SPI bus. (AMT CUI 203) Could you please help me to convert it ? Thank you !

#include <SPI.h>

#define CS 3 //Chip or Slave select 

uint16_t ABSposition = 0;
uint16_t ABSposition_last = 0;
uint8_t temp[2];    //This one.

float deg = 0.00;

void setup()
{
  pinMode(CS,OUTPUT);//Slave Select
  digitalWrite(CS,HIGH);
  SPI.begin();
  SPI.setBitOrder(MSBFIRST);
  SPI.setDataMode(SPI_MODE0);
  SPI.setClockDivider(SPI_CLOCK_DIV32);
  Serial.begin(115200);
  Serial.println("starting");
  Serial.flush();
  delay(2000);
  SPI.end();

}
uint8_t SPI_T (uint8_t msg)    //Repetive SPI transmit sequence
{
   uint8_t msg_temp = 0;  //vairable to hold recieved data
   digitalWrite(CS,LOW);     //select spi device
   msg_temp = SPI.transfer(msg);    //send and recieve
   digitalWrite(CS,HIGH);    //deselect spi device
   return(msg_temp);      //return recieved byte
}

void loop()
{ 
   uint8_t recieved = 0xA5;    //just a temp vairable
   ABSposition = 0;    //reset position vairable
   
   SPI.begin();    //start transmition
   digitalWrite(CS,LOW);
   
   SPI_T(0x10);   //issue read command
   
   recieved = SPI_T(0x00);    //issue NOP to check if encoder is ready to send
   
   while (recieved != 0x10)    //loop while encoder is not ready to send
   {
     recieved = SPI_T(0x00);    //cleck again if encoder is still working 
     delay(2);    //wait a bit
   }
   
   temp[0] = SPI_T(0x00);    //Recieve MSB
   temp[1] = SPI_T(0x00);    // recieve LSB
   
   digitalWrite(CS,HIGH);  //just to make sure   
   SPI.end();    //end transmition
   
   temp[0] &=~ 0xF0;    //mask out the first 4 bits
    
   ABSposition = temp[0] << 8;    //shift MSB to correct ABSposition in ABSposition message
   ABSposition += temp[1];    // add LSB to ABSposition message to complete message
    
   if (ABSposition != ABSposition_last)    //if nothing has changed dont wast time sending position
   {
     ABSposition_last = ABSposition;    //set last position to current position
     deg = ABSposition;
     deg = deg * 0.08789;    // aprox 360/4096
     Serial.println(deg);     //send position in degrees
     
   }   

   delay(30);    //wait a bit till next check

}

Please use

<<code>>
your code
<</code>>

when posting code to make it readable.

You may find you get more help if you make an attempt and ask for help when you hit a problem rather than just posting arduino code and expecting someone else to do all the work for you.

posted by Andy A 05 Oct 2018

Thanks for your help. this is the code I wrote :

#include "mbed.h"

Serial pc(USBTX, USBRX); // tx, rx


// SPI est une classe, faut pas appeler la variable avec le même nom
SPI _spi(PB_5, PB_4, PB_3);
DigitalOut cs(PC_7);

uint16_t ABSposition = 0;
uint16_t ABSposition_last = 0;
uint8_t temp[2];    //This one.
float deg = 0.00;

void wait_ms(int us);

uint8_t SPI_T (uint8_t msg)    //Repetive SPI transmit sequence
{
    uint8_t msg_temp = 0;  //vairable to hold recieved data
    cs=0;     //select spi device
    msg_temp = _spi.write(msg);    //send and recieve
    cs=1;    //deselect spi device
    return(msg_temp);      //return recieved byte
}

int main()
{

    cs=1;
    _spi.format(8,0);
    _spi.frequency(1000000);

    uint8_t recieved = 0xA5;    //just a temp vairable
    ABSposition = 0;    //reset position vairable

    while (true) {
        _spi.lock();
        //cs=0;
        SPI_T(0x10);   //issue read command
        //_spi.write(0x10);

        recieved = SPI_T(0x00);    //issue NOP to check if encoder is ready to send
        //recieved = _spi.write(0x00);    //issue NOP to check if encoder is ready to send

        while (recieved != 0x10) {  //loop while encoder is not ready to send
            recieved = SPI_T(0x00);    //cleck again if encoder is still working
            //recieved = _spi.write(0x00);    //issue NOP to check if encoder is ready to send


            wait_ms(20);
        }

        temp[0] = SPI_T(0x00);    //Recieve MSB
        temp[1] = SPI_T(0x00);    // recieve LSB
        //temp[0] = _spi.write(0x00);    //Recieve MSB
        //temp[1] = _spi.write(0x00);    // recieve LSB

        //cs=1;
        _spi.unlock();

        temp[0] &=~ 0xF0;    //mask out the first 4 bits

        ABSposition = temp[0] << 8;    //shift MSB to correct ABSposition in ABSposition message
        ABSposition += temp[1];    // add LSB to ABSposition message to complete message
 
        //if (ABSposition != ABSposition_last)    //if nothing has changed dont wast time sending position
        //{
        ABSposition_last = ABSposition;    //set last position to current position
        deg = ABSposition;
        //deg = deg * 0.08789;    // aprox 360/4096
   
       pc.printf("Valeur = %d", deg); //send position in degrees
        //}

        wait_ms(30);
    }
}


Do you think this is correct ? If yes, I think I have a hardware issue (I'm using a level converter because the SPI encoder is 5V)

I'm using Nucleo 64 STM32F401RE

posted by Vincent BIGIARINI 07 Oct 2018

1 Answer