Go Down

Topic: SPI : comment faire cohabiter 2 modules ? (Read 5877 times) previous topic - next topic

fdufnews

Par tout simplement je pensais à utiliser directement shiftIn et shiftOut. Qui sont simple d'utilisation.
C'est seulement après en reprenant la doc de ton senseur que j'ai vu que tous les transferts ne sont pas multiples de 8bits (plus particulièrement l'initialisation des transferts). Il faudrait regarder si l'émission de coups d'horloge supplémentaires en fin de cycle posent problème ou pas ce qui éviterait de devoir mettre le nez dans le code de shiftIn et shiftOut

hatoupix

 :smiley-eek-blue:

je fais comment pour générer un "coup d'horologe suplémentaire" ?  :smiley-eek:

68tjs

Les codes de shiftin/out sont déjà modifiés dans la version IDE Wiring 1.0 .
Il n'y a qu'à recopier.
Les Shadocks : L'ignorance ne s'apprend pas.

hatoupix

Les codes de shiftin/out sont déjà modifiés dans la version IDE Wiring 1.0 .
Il n'y a qu'à recopier.
je vais continuer à faire mon , j'ai bien téléchargé wiring 1.0 mais je ne trouve pas dedans le code contenant les shiftin et shift out ....

icare

Bonjour,
Sous Linux :
/usr/share/arduino/hardware/arduino/
tu as :
wiring_shift.c
@+
2B OR NOT(2B) = FF
Arduino 1.0.5 à 1.8.5 + gEdit + Ubuntu 18.04 LTS

hatoupix

Merci, j'ai bien la librairie wiring_shift avec les méthodes :

Code: [Select]

  shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder)
 
  shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val)


j'appelle les fonctions suivante dans mon code :
Code: [Select]

MS5541 PressSensor;
update
getPressureBar
get2ndTemperatureC


concernant le code d'origine de mon capteur, il faut que je change tout ce qui concerne SPI. par des shift_in ou shiftout ? ou simplement la déclaration ?

Code: [Select]

#include <SPI.h>
#include "MS5541.h"

MS5541::MS5541() {
SPI.begin();
  SPI.setBitOrder(MSBFIRST); 
SPI.setClockDivider(SPI_CLOCK_DIV32);
pinMode(9, OUTPUT);
  getCalibrationWord();
}

void MS5541::resetSensor() {
SPI.setDataMode(SPI_MODE0);
SPI.transfer(0x15);
SPI.transfer(0x55);
SPI.transfer(0x40);
}

void MS5541::update() {
TCCR1B = (TCCR1B & 0xF8) | 1 ; //generates the MCKL signal
analogWrite(9, 128);

//Pressure:
resetSensor();
SPI.transfer(0x0F); //send first byte of command to get pressure value
SPI.transfer(0x40); //send second byte of command to get pressure value
delay(35); //wait for conversion end
SPI.setDataMode(SPI_MODE1); //change mode in order to listen
presMSB = SPI.transfer(0x00); //send dummy byte to read first byte of value
presMSB = presMSB << 8; //shift first byte
presLSB = SPI.transfer(0x00); //send dummy byte to read second byte of value
D1 = presMSB | presLSB; //combine first and second byte of value
 
//Temperature
resetSensor();
SPI.transfer(0x0F); //send first byte of command to get temperature value
SPI.transfer(0x20); //send second byte of command to get temperature value
delay(35); //wait for conversion end
SPI.setDataMode(SPI_MODE1); //change mode in order to listen
tempMSB = SPI.transfer(0x00); //send dummy byte to read first byte of value
tempMSB = tempMSB << 8; //shift first byte
tempLSB = SPI.transfer(0x00); //send dummy byte to read second byte of value
D2 = tempMSB | tempLSB; //combine first and second byte of value

//calculate temp according to datasheet
dT = D2 - UT1;
if (dT < 0) {
dT2 = dT - (dT/128*dT/128)/2;
}
else {
dT2 = dT - (dT/128*dT/128)/8;
}

TEMP = (200 + dT*(C6+100)/pow(2,11))/10;
TEMPC = (200 + dT2*(C6+100)/pow(2,11))/10;

//calculate pressure according to datasheet
OFF = C2 + ((C4-250)*dT)/pow(2,12) + 10000;
SENS = C1/2 + ((C3+200)*dT)/pow(2,13) + 3000;
P = (SENS * (D1-OFF))/pow(2,11) + 1000;
}

float MS5541::getPressureMBar() {
return P;
}

float MS5541::getPressureBar() {
return P/1000.0;
}


float MS5541::getTemperatureC() {
return TEMP;
}

float MS5541::get2ndTemperatureC() {
return TEMPC;
}

float MS5541::getTemperatureF() {
return (TEMP*1.8)+32.0;
}

float MS5541::get2ndTemperatureF() {
return (TEMPC*1.8)+32.0;
}

void MS5541::getCalibrationWord() {
TCCR1B = (TCCR1B & 0xF8) | 1 ; //generates the MCKL signal
analogWrite(9, 128) ;

resetSensor();
SPI.transfer(0x1D); //send first byte of command to get calibration word 1
SPI.transfer(0x50); //send second byte of command to get calibration word 1
SPI.setDataMode(SPI_MODE1); //change mode in order to listen
result1 = SPI.transfer(0x00); //send dummy byte to read first byte of word
result1 = result1 << 8; //shift returned byte
inbyte1 = SPI.transfer(0x00); //send dummy byte to read second byte of word
result1 =  result1 | inbyte1; //combine first and second byte of word

resetSensor();
SPI.transfer(0x1D);
SPI.transfer(0x60);
SPI.setDataMode(SPI_MODE1);
result2 = SPI.transfer(0x00);
result2 = result2 <<8;
inbyte2 = SPI.transfer(0x00);
result2 = result2 | inbyte2;

resetSensor();
SPI.transfer(0x1D);
SPI.transfer(0x90);
SPI.setDataMode(SPI_MODE1);
result3 = SPI.transfer(0x00);
result3 = result3 <<8;
inbyte3 = SPI.transfer(0x00);
result3 = result3 | inbyte3;

resetSensor();
SPI.transfer(0x1D);
SPI.transfer(0xA0);
SPI.setDataMode(SPI_MODE1);
result4 = SPI.transfer(0x00);
result4 = result4 <<8;
inbyte4 = SPI.transfer(0x00);
result4 = result4 | inbyte4;

C1 = result1 >> 3 & 0x1FFF;
C2 = ((result1 & 0x07) << 10) | ((result2 >> 6) & 0x03FF);
C3 = (result3 >> 6) & 0x03FF;
C4 = (result4 >> 7) & 0x07FF;
C5 = ((result2 & 0x003F) << 6) | (result3 & 0x003F);
C6 = result4 & 0x007F;
UT1 = 8*C5 + 10000;
}



Merci !

hatoupix

pour modifier la commande : SPI.transfer(0x15) en utilisant shiftOut, je pense écrire : shiftOut(DATA_PIN,CLOCK_MS5541, uint8_t bitOrder,0x15)

mais il me manque l'information bitOrder ...


   

fdufnews

C'est la même chose que l'argument de la méthode setBitOrder() utilisée dans l'initialisation du SPI

hatoupix

MERCI !!!

Librairie modifiée !

mais ca marchotte : il y a un comportement étrange :

sketch SANS afficheur SPI + capteur Wire : OK --> données cohérentes
sketch AVEC afficheur SPI + capteur Wire : KO --> données recus incohérentes

librairie modifiée :
Code: [Select]
#include <SPI.h>
#include "wiring_shift.h"
#include "MS5541.h"

const uint8_t MS5541_CLOCK_DIVIDER = SPI_CLOCK_DIV32;
const int MS5541_DATA_PIN = 9;

MS5541::MS5541() {
//SPI.begin();
   //SPI.setBitOrder(MSBFIRST);  
//SPI.setClockDivider(SPI_CLOCK_DIV32); //divide 16 MHz to communicate on 500 kHz

pinMode(MS5541_DATA_PIN, OUTPUT);
   getCalibrationWord();
}

void MS5541::resetSensor() {
//SPI.setDataMode(SPI_MODE0);
//SPI.transfer(0x15);
shiftOut(MS5541_DATA_PIN,MS5541_CLOCK_DIVIDER, MSBFIRST,0x15);
//SPI.transfer(0x55);
shiftOut(MS5541_DATA_PIN,MS5541_CLOCK_DIVIDER, MSBFIRST,0x55);
//SPI.transfer(0x40);
shiftOut(MS5541_DATA_PIN,MS5541_CLOCK_DIVIDER, MSBFIRST,0x40);
}

void MS5541::update() {
TCCR1B = (TCCR1B & 0xF8) | 1 ; //generates the MCKL signal
analogWrite(MS5541_DATA_PIN, 128);

//Pressure:
resetSensor();
// SPI.transfer(0x0F); //send first byte of command to get pressure value
shiftOut(MS5541_DATA_PIN,MS5541_CLOCK_DIVIDER, MSBFIRST,0x0F);
// SPI.transfer(0x40); //send second byte of command to get pressure value
shiftOut(MS5541_DATA_PIN,MS5541_CLOCK_DIVIDER, MSBFIRST,0x40);
delay(35); //wait for conversion end
// SPI.setDataMode(SPI_MODE1); //change mode in order to listen
// presMSB = SPI.transfer(0x00); //send dummy byte to read first byte of value
presMSB = shiftIn(MS5541_DATA_PIN,MS5541_CLOCK_DIVIDER, MSBFIRST);
presMSB = presMSB << 8; //shift first byte
//presLSB = SPI.transfer(0x00); //send dummy byte to read second byte of value
presLSB = shiftIn(MS5541_DATA_PIN,MS5541_CLOCK_DIVIDER, MSBFIRST);
D1 = presMSB | presLSB; //combine first and second byte of value
 
//Temperature
resetSensor();
//SPI.transfer(0x0F); //send first byte of command to get temperature value
shiftOut(MS5541_DATA_PIN,MS5541_CLOCK_DIVIDER, MSBFIRST,0x0F);
//SPI.transfer(0x20); //send second byte of command to get temperature value
shiftOut(MS5541_DATA_PIN,MS5541_CLOCK_DIVIDER, MSBFIRST,0x20);
delay(35); //wait for conversion end
//SPI.setDataMode(SPI_MODE1); //change mode in order to listen
//tempMSB = SPI.transfer(0x00); //send dummy byte to read first byte of value
tempMSB = shiftIn(MS5541_DATA_PIN,MS5541_CLOCK_DIVIDER, MSBFIRST);
tempMSB = tempMSB << 8; //shift first byte
//tempLSB = SPI.transfer(0x00); //send dummy byte to read second byte of value
tempLSB = shiftIn(MS5541_DATA_PIN,MS5541_CLOCK_DIVIDER, MSBFIRST);
D2 = tempMSB | tempLSB; //combine first and second byte of value

//calculate temp according to datasheet
dT = D2 - UT1;
if (dT < 0) {
dT2 = dT - (dT/128*dT/128)/2;
}
else {
dT2 = dT - (dT/128*dT/128)/8;
}

TEMP = (200 + dT*(C6+100)/pow(2,11))/10;
TEMPC = (200 + dT2*(C6+100)/pow(2,11))/10;

//calculate pressure according to datasheet
OFF = C2 + ((C4-250)*dT)/pow(2,12) + 10000;
SENS = C1/2 + ((C3+200)*dT)/pow(2,13) + 3000;
P = (SENS * (D1-OFF))/pow(2,11) + 1000;
}

float MS5541::getPressureMBar() {
return P;
}

float MS5541::getPressureBar() {
return P/1000.0;
}


float MS5541::getTemperatureC() {
return TEMP;
}

float MS5541::get2ndTemperatureC() {
return TEMPC;
}

float MS5541::getTemperatureF() {
return (TEMP*1.8)+32.0;
}

float MS5541::get2ndTemperatureF() {
return (TEMPC*1.8)+32.0;
}

void MS5541::getCalibrationWord() {
TCCR1B = (TCCR1B & 0xF8) | 1 ; //generates the MCKL signal
analogWrite(MS5541_DATA_PIN, 128) ;

resetSensor();
//SPI.transfer(0x1D); //send first byte of command to get calibration word 1
shiftOut(MS5541_DATA_PIN,MS5541_CLOCK_DIVIDER, MSBFIRST,0x1D);
//SPI.transfer(0x50); //send second byte of command to get calibration word 1
shiftOut(MS5541_DATA_PIN,MS5541_CLOCK_DIVIDER, MSBFIRST,0x50);
//SPI.setDataMode(SPI_MODE1); //change mode in order to listen
//result1 = SPI.transfer(0x00); //send dummy byte to read first byte of word
result1 = shiftIn(MS5541_DATA_PIN,MS5541_CLOCK_DIVIDER, MSBFIRST);
result1 = result1 << 8; //shift returned byte
//inbyte1 = SPI.transfer(0x00); //send dummy byte to read second byte of word
inbyte1 = shiftIn(MS5541_DATA_PIN,MS5541_CLOCK_DIVIDER, MSBFIRST);
result1 =  result1 | inbyte1; //combine first and second byte of word

resetSensor();
//SPI.transfer(0x1D);
shiftOut(MS5541_DATA_PIN,MS5541_CLOCK_DIVIDER, MSBFIRST,0x1D);
//SPI.transfer(0x60);
shiftOut(MS5541_DATA_PIN,MS5541_CLOCK_DIVIDER, MSBFIRST,0x60);
//SPI.setDataMode(SPI_MODE1);
//result2 = SPI.transfer(0x00);
result2 = shiftIn(MS5541_DATA_PIN,MS5541_CLOCK_DIVIDER, MSBFIRST);
result2 = result2 <<8;
//inbyte2 = SPI.transfer(0x00);
inbyte2 = shiftIn(MS5541_DATA_PIN,MS5541_CLOCK_DIVIDER, MSBFIRST);
result2 = result2 | inbyte2;

resetSensor();
//SPI.transfer(0x1D);
shiftOut(MS5541_DATA_PIN,MS5541_CLOCK_DIVIDER, MSBFIRST,0x1D);
//SPI.transfer(0x90);
shiftOut(MS5541_DATA_PIN,MS5541_CLOCK_DIVIDER, MSBFIRST,0x90);
//SPI.setDataMode(SPI_MODE1);
//result3 = SPI.transfer(0x00);
result3 = shiftIn(MS5541_DATA_PIN,MS5541_CLOCK_DIVIDER, MSBFIRST);
result3 = result3 <<8;
//inbyte3 = SPI.transfer(0x00);
inbyte3 = shiftIn(MS5541_DATA_PIN,MS5541_CLOCK_DIVIDER, MSBFIRST);
result3 = result3 | inbyte3;

resetSensor();
//SPI.transfer(0x1D);
shiftOut(MS5541_DATA_PIN,MS5541_CLOCK_DIVIDER, MSBFIRST,0x1D);
//SPI.transfer(0xA0);
shiftOut(MS5541_DATA_PIN,MS5541_CLOCK_DIVIDER, MSBFIRST,0xA0);
//SPI.setDataMode(SPI_MODE1);
//result4 = SPI.transfer(0x00);
result4 = shiftIn(MS5541_DATA_PIN,MS5541_CLOCK_DIVIDER, MSBFIRST);
result4 = result4 <<8;
//inbyte4 = SPI.transfer(0x00);
inbyte4 = shiftIn(MS5541_DATA_PIN,MS5541_CLOCK_DIVIDER, MSBFIRST);
result4 = result4 | inbyte4;

C1 = result1 >> 3 & 0x1FFF;
C2 = ((result1 & 0x07) << 10) | ((result2 >> 6) & 0x03FF);
C3 = (result3 >> 6) & 0x03FF;
C4 = (result4 >> 7) & 0x07FF;
C5 = ((result2 & 0x003F) << 6) | (result3 & 0x003F);
C6 = result4 & 0x007F;
UT1 = 8*C5 + 10000;
}



hatoupix

2) utiliser un buffer sur DOUT que serait en haute impédance lorsque tu ne veux pas lire le MS5541. Cette solution évite d'utiliser des broches supplémentaires par contre elle oblige à ajouter un composant dans ton système. De plus même si le DOUT est déconnecté cela n'empêcherait pas le MS5541 de détecter un START dans le flux de données sur le SPI qui ne lui est pas destiné. Il faudrait donc débuter tous les transferts par un RESET tel qu'indiqué dans la doc du composant.
Je déterre mon sujet, car j'ai finalement opté pour la solution hard avec un 1G125 ... le problème pour moi est maintenant : comment l'implémenter ? et y a t il une modif de code à faire  :smiley-roll-blue:

Merci a vous !

Go Up