Shop OBEX P1 Docs P2 Docs Learn Events
Problem with Multicore Programming — Parallax Forums

Problem with Multicore Programming

Hi,

I'm trying to read gyroscope and accelerometer data in a second core and print the values from that same core. However, the outputted values are all the same when I try to run in a different core. The same block of code that reads the sensors works perfectly fine when run in core 0. My code is posted below. Please help.
/*
Test Multicore
*/
#include "simpletools.h"                      // Include simple tools

// Variables for gyro
volatile signed int whoAmI;
volatile signed int xL, xH, yL, yH, zL, zH;
volatile signed int statusReg;
volatile float gx, gxSum, gxAvg, gy, gySum, gyAvg, gz, gzSum, gzAvg;

// Variables for accel
volatile signed char x, y, z;                                                          // Z-axis value, *must be a signed char*
volatile int axSum, axAvg, xOffset, aySum, ayAvg, yOffset, azSum, azAvg, zOffset;

// Gyro pins
volatile int CS=11;
volatile int SCL=10;
volatile int SDA=9;

unsigned int stack[40+25];
int cog;
void data();
int main(){                                    // Main function

// get gyroscope initializations
  high(CS);                                             //CS line high (SPI inactive)
  low(SCL);                                              //CLK line low (prepares chip to send brief high signals or clock pulses)
  
  low(CS);
  shift_out(SDA, SCL, MSBFIRST, 8, 0b10001111);           //Send read register address (whoAmI)
  whoAmI = shift_in(SDA, SCL, MSBPRE, 8);
  high(CS);
  
  if(whoAmI == 0b11010011){
    print("Device ID Correct: %b\n", whoAmI);
  }
  else{
    print("Device ID Incorrect: %b\n", whoAmI);
  }   

  //Register 4 - Set 3-wire SPI
  low(CS);                                              //CS line low (start SPI)
  shift_out(SDA, SCL, MSBFIRST, 8, 0b00100011);           //Write MCTL register (register 4)to set 3-wire SPI
  shift_out(SDA, SCL, MSBFIRST, 8, 0b10010001);           //Value for MCTL register (register 4) to set 3-wire SPI
  high(CS);
  
  //Register 1 - Set 100Hz output rate, 25Hz cutoff freq, normal mode, enable all axes
  low(CS);
  shift_out(SDA, SCL, MSBFIRST, 8, 0b01100000);           //Write MCTL register (register 1)
  shift_out(SDA, SCL, MSBFIRST, 8, 0b00011111);           //Value for MCTL register (register 1)
  high(CS);                                             //CS high(stop SPI)
  
  // get accel initializations
  high(6);                                                                    // CS line high (inactive)
  low(8);                                                                     // CLK line low
  low(6);                                                                     // CS line low (start SPI)
  
  shift_out(7, 8, MSBFIRST, 8, 0b10101100);                                    // Write MCTL register
  shift_out(7, 8, MSBFIRST, 8, 0b01100101);                                   // Value for MCTL register
  high(6);                                                                    // CS line high (stop SPI)
  
  pause(100);
  
  simpleterm_close();
  cog = cog_run(data,128);
  //cogstart(data, NULL, stack, sizeof(stack));
   
}

void data(){
  simpleterm_open();
  while(1){
   
    // get gyroscope data
    // x-axis
    low(CS);                                            //CS low selects chip
    shift_out(SDA, SCL, MSBFIRST, 8, 0b10101000);         //Send read register address (OUT_X_L)
    xL = shift_in(SDA, SCL, MSBPRE, 8);                   //Get value from register
    high(CS);                                           //De-select chip with CS line high
    
    low(CS);
    shift_out(SDA, SCL, MSBFIRST, 8, 0b10101001);         //Send read register address (OUT_X_H)
    xH = shift_in(SDA, SCL, MSBPRE, 8);                   //Get value from register
    high(CS);
    gx = (short) (((xH<<8) | xL)-gxAvg)*.0175*PI/180;
    
    // y-axis
    low(CS);                                            //CS low selects chip
    shift_out(SDA, SCL, MSBFIRST, 8, 0b10101010);         //Send read register address (OUT_Y_L)
    yL = shift_in(SDA, SCL, MSBPRE, 8);                   //Get value from register
    high(CS);                                           //De-select chip with CS line high
    
    low(CS);
    shift_out(SDA, SCL, MSBFIRST, 8, 0b10101011);         //Send read register address (OUT_Y_H)
    yH = shift_in(SDA, SCL, MSBPRE, 8);                   //Get value from register
    high(CS);
    gy = (short) (((yH<<8) | yL)-gyAvg)*.0175*PI/180;
    
    // z-axis
    low(CS);                                            //CS low selects chip
    shift_out(SDA, SCL, MSBFIRST, 8, 0b11101100);         //Send read register address (OUT_Z_L)
    zL = shift_in(SDA, SCL, MSBPRE, 8);                   //Get value from register
    high(CS);                                           //De-select chip with CS line high
   
    low(CS);
    shift_out(SDA, SCL, MSBFIRST, 8, 0b10101101);         //Send read register address (OUT_Z_H)
    zH = shift_in(SDA, SCL, MSBPRE, 8);                   //Get value from register
    high(CS);
    gz = (short) (((zH<<8) | zL)-gzAvg)*.0175*PI/180;            //2's complement operation, subtract zero rate offset, multiply by 
                                                        //sensitivity value for 500deg/s, "short" needed for 2's complement
    print("gx = %f  gy = %f  gz = %f\n",gx*180/PI,gy*180/PI,gz*180/PI);
  
    // get accel data 
    //x-axis
    low(6);                                                                  // CS low selects chip
    shift_out(7, 8, MSBFIRST, 8, 0b00001100);                                  // Send read register address, z-axis    
    x = shift_in(7, 8, MSBPRE, 8);                                            // Get value from register
    x = x-xOffset;
    float ax = (float) x;
    ax = ax/64;    
    high(6);                         
    
    //y-axis
    low(6);                                                                  // CS low selects chip
    shift_out(7, 8, MSBFIRST, 8, 0b00001110);                                  // Send read register address, z-axis    
    y = shift_in(7, 8, MSBPRE, 8);                                            // Get value from register
    y = y-yOffset;
    float ay = (float) y;
    ay = ay/64;           
    high(6);                         
    
    //z-axis
    low(6);                                                                   // CS low selects chip
    shift_out(7, 8, MSBFIRST, 8, 0b00010000);                                  // Send read register address, z-axis    
    z = shift_in(7, 8, MSBPRE, 8);                                            // Get value from register
    z = z-zOffset;
    float az = (float) z;
    az = az/64;      
    high(6);                                                                  // De-select chip
//  print("ax = %f  ay = %f  az = %f\n",ax,ay,az);          // Display measurement
  }    
}

Comments

  • Looks like both Main core and data core are constantly accessing the external device, Main keeps initializing it while data keeps trying to get data.
  • Hal,

    Thanks for your response. I am confused because there is no while loop in main so doesn't it just run through main and stop when it gets to the end?
  • You are right, too much Arduino crossing over. Sorry about that.
  • Haha no worries. Might you have any other ideas to try?
  • It looks like you're starting a new COG but then letting the main COG exit. I'm not sure what happens in that case. You might want to add this code to the end of your main function:
        while (1)
            ;
    
  • Have you tried putting the initialization code into the data function for the 2nd cog?
  • Hal,

    That worked! Adding initializations to the data core is what I needed to do. Thanks very much.

    David,

    Unfortunately adding the while loop to main didn't work, but thanks so much for the suggestion.
  • Actually, my suggestion might have made things worse. You are accessing the same pins from both COGs so if the main COG leaves a pin high and it doesn't exit then the data COG won't be able to pull it low. It's probably best to have all accesses to a particular pin in the same COG.
  • Okay, that makes sense. I will keep that in mind moving forward.
  • Good to hear. One very minor correction, probably inconsequential, but when declaring the cog variable, it should be done as a pointer to prevent a warning during compile.
    int *cog;
    

    Otherwise you get:
    cog = cog_run(data,128);
    
    is flagged with
    test_multicore.c:66:7: warning: assignment makes integer from pointer without a cast [enabled by default]
    
  • Thank you, I will make this correction.
Sign In or Register to comment.