Hi guys,
I am having some issues with a MLX90316 Magnetic Rotary on an Arduino UNO.
The code I am using is
/* MLX90316 Rotary Position Sensor
* KHM 2010 / Martin Nawrath
* Kunsthochschule fuer Medien Koeln
* Academy of Media Arts Cologne
* MLX90316KDC-BDG-100-RE Rotary Position Sensor
* K=Temperature Range -40ºC to 125ºC
* DC = SOIC150
* BDG = SPI Version
* 100 = SPI
* RE = Reel
* MOSI (Master Out Slave In) the master sends a commant to the slave to get the angle out.
* MLX90316.cpp sets _SS, SCLK, and MOSI to OUTPUT in beginning, sets MOSI to INPUT at the end.
* readAngle is 10 x angle, thus 3600 is 360.0º
*/
// in this sketch the sensor does not communicates using the "SPI.h library"
#include "Metro.h" //Include Metro library
#include "MLX90316.h" // Include MLX90316 library
int pin_SS = 10; // White Wire
int pinSCLK = 13; // Violet Wire
int pinMOSI = 11; // Grey Wire
int ii;
int angle;
Metro mlxMetro = Metro(5);
MLX90316 mlx_1 = MLX90316();
void setup(){
Serial.begin(115200); //Initializes the SPI bus by setting SCK, MOSI, and SS to outputs, pulling SCK and MOSI low, and SS high.
mlx_1.attach(pin_SS,pinSCLK, pinMOSI );
Serial.println(" MLX90316 Rotary Position Sensor");
}
void loop() {
if (mlxMetro.check() == 1) {
ii = mlx_1.readAngle();
angle = ii/10; //readAngle gives 10 * degrees, thus 3600 = is 360.0º
/* if ii = -1 then no SPI signal
* if ii = -2 then signal too strong
* if ii = -3 then signal too weak
* "angle" will read 0 if signal is lost
*/
Serial.print(angle);
Serial.println("");
}
}
/*
MLX90316.cpp - Library to use with Melexis MLX90316 rotary encoder chip.
Created by Martin Nawrath KHM 2010.
http://interface.khm.de
Released into the public domain.
*/
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#include "MLX90316.h"
// constructor
MLX90316::MLX90316(){
};
// attach
void MLX90316::attach(int pinSS, int pinSCK, int pinMOSI )
{
_pinSS = pinSS;
_pinSCK = pinSCK;
_pinMOSI = pinMOSI;
pinMode(_pinSS , OUTPUT);
pinMode(_pinSCK , OUTPUT);
pinMode(_pinMOSI , OUTPUT);
}
//******************************************************
int MLX90316::readAngle() {
byte bb;
int ret=-1;
unsigned int rr;
long int lo;
digitalWrite(_pinSS,0);
delay(2);
bb=_spiByte(0x55); // send sync byte ( AA reversed order = 55?)
bb=_spiByte(0xFF); // send sync byte FF)
bb=_spiByte(0xFF); // receive 1. byte of mlx msb data
rr= (bb << 8);
bb=_spiByte(0xFF); // receive 2. byte of lsb mlx data
rr=rr+bb;
if ((rr & 3) == 2) {
if ( rr & (1 << 4)) ret=-2; // signal to strong
if ( rr & (1 << 5)) ret=-3; // signal to weak
}
if ((rr & 3) == 1) { // valid angle data ?
rr = (rr >> 2);
lo= rr ;
lo=lo * 3600 / 16384; // scale output to 360 deg, units in tens of deg.
ret= lo;
}
digitalWrite(_pinSS,1);
return(ret);
}
//*************************************************************
// send and receive SPI byte to/from MLX90316 Chip
uint8_t MLX90316::_spiByte(uint8_t tx) {
byte rxb=0;
for (int ix = 0; ix < 8; ix++){ // receive/transmit 8 SPI bits
digitalWrite(_pinMOSI,0); // turn port internal pullup resistor off
pinMode(_pinMOSI,OUTPUT); // switch MOSI pin to output
// write SPI transmit bit to sensor
if ((tx & 1) != 0) digitalWrite(_pinMOSI,1);
else digitalWrite(_pinMOSI,0);
tx= ( tx >> 1);
pinMode(_pinMOSI,INPUT); // switch MOSI pin to input
digitalWrite(_pinMOSI,1); // turn port internal pullup resistor on
digitalWrite(_pinSCK,1); // clocksignal positive slope
digitalWrite(_pinSCK,0); // clocksignal negative slope
rxb = ( rxb << 1); // shift received byte left
if (digitalRead(_pinMOSI) ==1) rxb = rxb | 1; // read respose bit from sensor
digitalWrite(_pinMOSI,0); // turn port internal pullup resistor off
pinMode(_pinMOSI,OUTPUT); // switch MOSI pin to output
}
return(rxb);
}
I have the output of the rotary connected to pin 11, the /SS to pin 10, and SCLK to pin 13.
On the serial monitor, I am receiving straight '1's or if the rotary is turned to a certain position, I get all '0's. I thought the code was right...