Go Down

Topic: SPI, MLX90333 troubleshooting (Read 591 times) previous topic - next topic

Gillam

I've been troubleshooting trying to get data from a Mikroelectronica 3D Hall Click
(https://www.mikroe.com/3d-hall-click) board for 3 days now, and could really use some help or suggestions.  This is my first attempt at using SPI and the SPI library.  I'm also self taught as far as programming goes, so apologize in advance for any unusual coding.

This board is mounted with a Melexis MLX90333 chip, programmed for SPI communication.  Mikroelectronica provides proprietary libraries for C implementations on generic avr microcontrollers, but nothing for Arduino.  The board appears to be configured according to what Melexis recommends for SPI application, as described on page 42 of the MLX90333 datasheet

http://www.melexis.com/Asset/MLX90333-Datasheet-DownloadLink-5276.aspx

I'm trying to implement this on an UNO, and have tried both the 10,11,12,13 pins as SS, MOSI, MISO and SCK, as well as the ICSP pins.  Here is the code I'm using.

Code: [Select]
#include <SPI.h>
#include <stdint.h>

uint16_t dataBuffer[8];

void setup() {
  Serial.begin(9600);
  SPI.begin;
  pinMode(SS, OUTPUT);
}

void loop() {
  delay(20); //MLX90333 startup takes 16ms
  SPI.beginTransaction(SPISettings(7000000, LSBFIRST, SPI_MODE1));
  digitalWrite(SS, LOW);
  delay(5);
  int i;
  for (i=0; i<8; i++){
  dataBuffer[i] = SPI.transfer(0x00);
  delay(20);
  }
  digitalWrite(SS, HIGH);
  SPI.endTransaction();
  delay(1500);
 
  deBugArray1(dataBuffer,"Data",8); //print dataBuffer array elements to serial monitor
  delay(1000);
}

  //****Printing array values************************
void deBugArray1(uint16_t array1[], String varName, int col){   //print 1 dimensional array contents
  Serial.println(varName);
  int a=0;
  for(a==0; a<col; a++){
    Serial.print(array1[a],8);
    Serial.print(" ,");
    delay(100);
  }
    Serial.println();
}



The MLX90333 datasheet indicates that least significant byte is first, the master clock is set to 7MHz, CPHA=1 and  CPOL=0, therefore SPI_MODE1.

The data frame layer is 8 bytes, where the 1st byte is a startbyte, the 2nd and 3rd are the alpha angle of the magnetic field, 4th and 5th are the beta angle, 6th and 7th are error code, and 8th is check sum.

In the code above I am trying to transmit/receive 1 byte at a time and am somewhat guessing that my code is doing that or trying to.

The output I'm getting is either all 0's, or all 377, with no rhyme or reason for either, while moving a magnet about the chip.

i.e. Serial Monitor output

Data
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
Data
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
Data
377 ,377 ,377 ,377 ,377 ,377 ,377 ,377 ,
etc...

I've tried various combinations of SPI SETTINGS, clock speeds, modes, MSB/LSB, with no real effect.

The LED on the Mikro Click board is lit up, so power is on.  I have 2 such boards and am getting the same result with each.  I've also set it up on a MEGA2560 with the same results.

If anyone can spot something I'm doing wrong or suggest some troubleshooting way forward I would really appreciate it.
 

pylon

Quote
The MLX90333 datasheet indicates that least significant byte is first
LSB and MSB correspond to Least Significant Bit and Most Significant Bit. The datasheet indicates that MSB is used.

Quote
I'm trying to implement this on an UNO, and have tried both the 10,11,12,13 pins as SS, MOSI, MISO and SCK, as well as the ICSP pins.
How did you exactly connect these pins? The chips doesn't support real SPI but only a cut down version of it. MISO/MOSI is a shared pin and the hardware serial interface doesn't support that to my knowledge.
If you connect both pins together you produce a short circuit as MOSI won't go tri-state.
Unfortunately I don't see another solution than to bit-bang the interface using GPIOs.

Gillam

Thanks for pointing that out Pylon.

I got headfaked by the LSByte reference in the table at the top of page 38 of the datasheet.

The 3d Hall Click board that the chip is on, has what I think is a mosfet that splits that single MISO/MOSI from the chip into separate SDO and SDI pins on the board, as per the schematic in section 16.4 of the datasheet.  What this might imply as far as how MISO and MOSI should be handled is well beyond me.

I've tried a slower clock speed, in case of noise, as well as MSB in the settings.  Still the same result, although the output would switch from all 0's to all 377's with a magnetic field being introduced, so at least seeing some sort of response.

Really appreciate your help. 

Gillam

Well, finally have something :o

The following code is working, so hopefully save someone else hours of messing around should they try to implement this board/chip.

Code: [Select]
#include <SPI.h>
#include <stdint.h>

//*******Arduino UNO SPI pins********
#define SS 10   //brown
#define SCK 13  //blue
#define MOSI 11  //SDI MOSI green
#define MISO 12  //SDO MISO yellow

byte dataBuffer[8];

void setup() {
  Serial.begin(9600);
  SPI.begin;
  pinMode(SS, OUTPUT);   //
  pinMode(SCK, OUTPUT);  // All necessary though SPI.begin should take care of this
  pinMode(MOSI, OUTPUT); //
  pinMode(MISO, INPUT);  //
}

void loop() {
  delay(20); //MLX90333 startup takes 16ms
  SPI.beginTransaction(SPISettings(160000, MSBFIRST, SPI_MODE1)); //320000 is about max
  delay(5);
  int j;
  for (j=0; j<10; j++){
    digitalWrite(SS, LOW);
    delay(20);  //Short delay necessary here
    int i;
    for (i=0; i<8; i++){
      dataBuffer[i] = SPI.transfer(255);  // Must transfer 1's, 0's don't work
      }
    digitalWrite(SS, HIGH);
    SPI.endTransaction();
    Serial.print(dataBuffer[2],8); //Print 3rd byte, MSB for Alpha
    Serial.print(" ,");
    Serial.print(dataBuffer[4],8); //Print 5th byte, MSB for Beta
    Serial.println(" ,");
    }
  }


A few observations:

I had to use the default SPI pins, 10, 11, 12, 13 for UNO.  ICSP pins were not working.
Also had to set the pins to their proper function, OUTPUT or INPUT.  I thought the SPI.begin would deal with that, but it wouldn't work without setting them in the code.
The max value for the clock speed in the SETTINGS function is about 320000. At 640000 and above, 0's and garbage.  I settled on 160000.
A short delay is necessary after setting SS to LOW, prior to SPI.transfer.
SPI.transfer must be all 1's (255).  0's return 0's.  This might be how that Mosfet on the board that splits out the MISO/MOSI from the chip works?
The data frame consists of 8 bytes, where the 2nd and 3rd are Alpha(LSByte first), and the 4th and 5th are Beta(LSByte first).  I'm therefore printing just the MSByte of Alpha and Beta while testing with a magnet.
The output in the absence of a magnetic field is random numbers or noise.  You need a field for it to settle down, and then only the MSBytes are fairly constant, though I'm sure if everything were held firmly in housings with things soldered together, the LSBytes would stabilize.
The downer is that it turns out the ring magnet I have is polarized axially( N on the top, flat side and S on the bottom flat side.  I need it polarized so that as the disk spins like a CD, N and S would swap ends. :smiley-confuse:

Gillam

P.S. Just spotted my error on SPI.begin ( no () ).  The pin states (INPUT, OUTPUT) do not have to be spelled out in the code.

pylon

Quote
I had to use the default SPI pins, 10, 11, 12, 13 for UNO.  ICSP pins were not working.
This is almost impossible, they are connected onboard.

Quote
Also had to set the pins to their proper function, OUTPUT or INPUT.  I thought the SPI.begin would deal with that, but it wouldn't work without setting them in the code.
You must do that for the SS pin only, you must not do that for the other pins.

Quote
The max value for the clock speed in the SETTINGS function is about 320000. At 640000 and above, 0's and garbage.  I settled on 160000.
That (160000) would correspond with the timings on page 36 of the datasheet.

Quote
A short delay is necessary after setting SS to LOW, prior to SPI.transfer.
Which is also mentioned on page 36.


Hen94

Hey, I am having a similar issue to you trying to get the Melexis MLX90333 working with an arduino. Mine only outputs zeros over the serial monitor and I cannot understand why.
Thanks

pylon

Quote
Mine only outputs zeros over the serial monitor and I cannot understand why.
Just a wild guess as you provide almost no information: Your wiring is wrong or your sketch contains an error.

Go Up