AVR Duino és SPI eszköz használata
AVR Duino és SPI eszköz használata
Van egy AVR Duino panelem. Az Arduino programmal tudom programozni.
Szeretném egy nyomásmérő SPI adatvonalát olvasni vele.
Első körkérdésre azt kaptam, hogy miért nem I2C, meg hogy kössem fel a gatyám.
Szóval elbátortalanodtam, azonban valahogy meg kéne oldani.
Kezdő vagyok, szóval szívesen veszem a segítséget, cserébe szívesen tanulok.
Szeretném egy nyomásmérő SPI adatvonalát olvasni vele.
Első körkérdésre azt kaptam, hogy miért nem I2C, meg hogy kössem fel a gatyám.
Szóval elbátortalanodtam, azonban valahogy meg kéne oldani.
Kezdő vagyok, szóval szívesen veszem a segítséget, cserébe szívesen tanulok.
Még keveset Tudsz a SPI-röl!
Ez kifejezetten Arduino:
http://tronixstuff.wordpress.com/2011/0 ... e-spi-bus/
AVR151: Setup And Use of The SPI
http://www.atmel.com/Images/doc2585.pdf
Mit hova, miért?
http://winavr.scienceprog.com/avr-gcc-t ... llers.html
+ az AVR-ed adatlapja. Mert abból is van pár fajta.
Sajnos még magyar fordítás nincsen róla.
Ez kifejezetten Arduino:
http://tronixstuff.wordpress.com/2011/0 ... e-spi-bus/
AVR151: Setup And Use of The SPI
http://www.atmel.com/Images/doc2585.pdf
Mit hova, miért?
http://winavr.scienceprog.com/avr-gcc-t ... llers.html
+ az AVR-ed adatlapja. Mert abból is van pár fajta.
Sajnos még magyar fordítás nincsen róla.
Ezt a programot használom - erre redukáltam az exaples könyvtárban található SPI barométeres programját.
Van pár dolog, amit nem értek.
Ez a HSC Honeywell nyomás érzékelő SPI-je úgy működik, hogy a chip select aktiválása után az addig low clock felfut high-ra, majd amikor lefutó éle lesz, akkor lehet eltárolni a MISO lábon levő adatot.
Ez az érzékelő első 2x8 bit átküldése után akár az adatátvitel meg is szüntethető, vagyis a chip select high-ba megy.
Ha ki akarnám olvasni a további adatokat is (amiről amúgy az érzékelő adatlapja szemérmesen hallgat, ami hőmérséklet érték lehet), akkro a chip selectet nem a 16. órajel után, hanem 24., vagy a 32. után kell visszavenni.
Namost a mintaprogram a barométer olvasós, az olyan eszközt használ - gondolom, amely regiszterekben tárolja a mért adatokat.
Ez a Honeywell érzékelő pedig folytonos bitsorozatot ad (vagy vesszük el tőle - nézőpont kérdése).
No itt akadtam meg.
1. Hogyan tudnám megtanítani ennek a programnak, hogy ne regisztereket olvasson, hanem 16, 24 vagy 32 hosszú bitsorozatot.
2. Kell-e állítani a SPI.setDataMode(SPI_MODE1); -ot?
3. vajon az eredeti program (BarometricPressureSensor nevű program) miért használ hasonló adatokhoz más deklarációt? Az egyik helyen ezt írja:
unsigned int pressure_data_high =.......
a másik helyen pedig: byte pressure_data_low =.........
Idemásolom azt, ami jelenleg fut.
------------- ennek eredménye az, hogy a low és a high érték is ugyanaz, valamint 7 a kezdeti érték, és 63 a legnagyobb érték.
Ez az érzékelő első két bitje egy állapotjelző bit.
Mondjuk jó lenne ezeket külön beolvasni egy -egy változóba, aztán jön 6 biten a high és utána 8 biten a low byte.
át idáig jutottam.
Mit javasoltok, illetve mit tudtok mondani a kérdéseimre?
Csaba
Van pár dolog, amit nem értek.
Ez a HSC Honeywell nyomás érzékelő SPI-je úgy működik, hogy a chip select aktiválása után az addig low clock felfut high-ra, majd amikor lefutó éle lesz, akkor lehet eltárolni a MISO lábon levő adatot.
Ez az érzékelő első 2x8 bit átküldése után akár az adatátvitel meg is szüntethető, vagyis a chip select high-ba megy.
Ha ki akarnám olvasni a további adatokat is (amiről amúgy az érzékelő adatlapja szemérmesen hallgat, ami hőmérséklet érték lehet), akkro a chip selectet nem a 16. órajel után, hanem 24., vagy a 32. után kell visszavenni.
Namost a mintaprogram a barométer olvasós, az olyan eszközt használ - gondolom, amely regiszterekben tárolja a mért adatokat.
Ez a Honeywell érzékelő pedig folytonos bitsorozatot ad (vagy vesszük el tőle - nézőpont kérdése).
No itt akadtam meg.
1. Hogyan tudnám megtanítani ennek a programnak, hogy ne regisztereket olvasson, hanem 16, 24 vagy 32 hosszú bitsorozatot.
2. Kell-e állítani a SPI.setDataMode(SPI_MODE1); -ot?
3. vajon az eredeti program (BarometricPressureSensor nevű program) miért használ hasonló adatokhoz más deklarációt? Az egyik helyen ezt írja:
unsigned int pressure_data_high =.......
a másik helyen pedig: byte pressure_data_low =.........
Idemásolom azt, ami jelenleg fut.
Kód: Egész kijelölése
/*
HSC Honeywell nyomás érzékelő SPI olvasása
AN kivitelnél a lábliosztás:
1 GND
2 Vsupply
3 MISO
4 SCLK
5 SS
6, 7, 8 - nincs használva
HSC érzékelőhöz rendelt kivezetések:
pins 10, 12, 13:
SS: pin 10
MOSI: pin 11 - nincs használva
MISO: pin 12
SCLK: pin 13
created 2012 júmius 12.
modified xxxxxxxxxxxxxxxxx
by csabaffy Tom Igoe munkája alapján
*/
// the sensor communicates using SPI, so include the library:
#include <SPI.h>
//Sensor's memory register addresses - megöröklött változók, nem mind kell?:
const int PRESSURE = 0;
const int PRESSURE_LSB = 0;
const byte READ = 0;
//
//az arduino panelnak megfelelően a pin 10 adja a chip select jelet
const int chipSelectPin = 10;
void setup() {
Serial.begin(9600);
// start the SPI library:
SPI.begin();
// initalize the chip select pin:
pinMode(chipSelectPin, OUTPUT);
//SPI.setDataMode(mode)
//Parameters
//mode: SPI_MODE0, SPI_MODE1, SPI_MODE2, or SPI_MODE3
//Clock idle = low vagyis az órajel amíg várakozik, addig low,
//az adat az órajel lefutó élénél érvényes, vagyis "active to idle (high to low)"
//ez a Mode1
SPI.setDataMode(SPI_MODE1);
delay(2000);
}
void loop() {
//readRegister beolvasná az első bytot
//paraméterei
//1. melyik regisztert, a
//2. hanyadik byt-tól bytesToRead nevű változó veszi át ezt a paramétert, innen gondolom.
unsigned int pressure_data_high = readRegister(0x00, 0);
Serial.println("\tpressure_data_high=" + String(pressure_data_high));
//Read the pressure data lower 16 bits:
//unsigned int pressure_data_low = readRegister(0x00, 1);
byte pressure_data_low = readRegister(0x00, 1);
Serial.println(" low=" + String(pressure_data_low));
//összesítve a két byte - addig, amíg nem tudok jó értékeket látni a high és a low -n, addig ezt kivettem:
// long pressure = ((pressure_data_high << 8) | pressure_data_low);
// display the pressure - kiirást kivettem, addig, amíg jó nem lesz.:
// Serial.println("\tPressure [Pa]=" + String(pressure));
delay(1000);
}
// az elmaradt if zárójele}
//Read from the HSC preasure sensor:
unsigned int readRegister(byte thisRegister, int bytesToRead ) {
byte inByte = 0; // incoming byte from the SPI
unsigned int result = 0; // result to return
Serial.print("\t");
// take the chip select low to select the device:
digitalWrite(chipSelectPin, LOW);
// send the device the register you want to read:
//SPI.transfer(dataToSend);
// send a value of 0 to read the first byte returned:
result = SPI.transfer(0x0000);
// decrement the number of bytes left to read:
bytesToRead--;
// if you still have another byte to read:
if (bytesToRead > 0) {
// shift the first byte left, then get the second byte:
result = result << 8;
inByte = SPI.transfer(0x01);
// combine the byte you just got with the previous one:
result = result | inByte;
// decrement the number of bytes left to read:
bytesToRead--;
}
// take the chip select high to de-select:
digitalWrite(chipSelectPin, HIGH);
// return the result:
return(result);
}
Ez az érzékelő első két bitje egy állapotjelző bit.
Mondjuk jó lenne ezeket külön beolvasni egy -egy változóba, aztán jön 6 biten a high és utána 8 biten a low byte.
át idáig jutottam.
Mit javasoltok, illetve mit tudtok mondani a kérdéseimre?
Csaba
köszi, megvan.
Kód: Egész kijelölése
/*
HSC Honeywell nyomás érzékelő SPI olvasása
AN kivitelnél a lábliosztás:
1 GND, 2 Vsupply, 3 MISO, 4 SCLK, 5 SS, 6, 7, 8 - nincs használva
HSC érzékelőhöz rendelt kivezetések:
pins 10, 12, 13:
SS: pin 10
MOSI: pin 11 - nincs használva
MISO: pin 12
SCLK: pin 13
created 2012 júmius 12.
modified xxxxxxxxxxxxxxxxx
by csabaffy Tom Igoe munkája alapján
irodalom: http://www.rosseeld.be/DRO/PIC/SPI_Timing.htm
http://tronixstuff.wordpress.com/2011/05/13/tutorial-arduino-and-the-spi-bus/
http://www.atmel.com/Images/doc2585.pdf
*/
// the sensor communicates using SPI, so include the library:
#include <SPI.h>
//Sensor's memory register addresses - megöröklött változók, nem mind kell?:
const int PRESSURE = 0;
const int PRESSURE_LSB = 0;
const byte READ = 0;
//
//az arduino panelnak megfelelően a pin 10 adja a chip select jelet
const int chipSelectPin = 10;
void setup() {
Serial.begin(9600);
// start the SPI library:
SPI.begin();
// initalize the chip select pin:
pinMode(chipSelectPin, OUTPUT);
//SPI.setDataMode(mode)
//Parameters
//mode: SPI_MODE0, SPI_MODE1, SPI_MODE2, or SPI_MODE3
//Clock idle = low vagyis az órajel amíg várakozik, addig low,
//az adat az órajel lefutó élénél érvényes, vagyis "active to idle (high to low)"
//ez a Mode1
SPI.setDataMode(SPI_MODE1);
delay(2000);
}
void loop() {
//readRegister beolvasná az első bytot
//paraméterei
//1. melyik regisztert, a
//2. hanyadik byt-tól bytesToRead nevű változó veszi át ezt a paramétert, innen gondolom.
unsigned int pressure_data_high = readRegister(0x00, 0);
Serial.println("\tpressure_data_high=" + String(pressure_data_high));
//Read the pressure data lower 16 bits:
//unsigned int pressure_data_low = readRegister(0x00, 1);
// byte pressure_data_low = readRegister(0x00, 1);
// Serial.println(" low=" + String(pressure_data_low));
//összesítve a két byte - addig, amíg nem tudok jó értékeket látni a high és a low -n, addig ezt kivettem:
// long pressure = ((pressure_data_high << 8) | pressure_data_low);
// display the pressure - kiirást kivettem, addig, amíg jó nem lesz.:
// Serial.println("\tPressure [Pa]=" + String(pressure));
delay(1000);
}
// az elmaradt if zárójele}
//Read from the HSC preasure sensor:
unsigned int readRegister(byte thisRegister, int bytesToRead ) {
byte inByte = 0; // incoming byte from the SPI
unsigned int result = 0; // result to return
Serial.print("\t");
// take the chip select low to select the device:
digitalWrite(chipSelectPin, LOW);
// send the device the register you want to read:
//SPI.transfer(dataToSend);
// send a value of 0 to read the first byte returned:
byte result1 = SPI.transfer(0);
Serial.print(result1);
// decrement the number of bytes left to read:
//bytesToRead--;
// if you still have another byte to read:
// if (bytesToRead > 0) {
// shift the first byte left, then get the second byte:
result = result1 << 8;
byte result2 = SPI.transfer(0);
// inByte = SPI.transfer(0x01);
// combine the byte you just got with the previous one:
result = result | result2;
// decrement the number of bytes left to read:
// bytesToRead--;
// }
// take the chip select high to de-select:
digitalWrite(chipSelectPin, HIGH);
// return the result:
return(result);
}
http://forum.sparkfun.com/viewtopic.php?f=8&t=23965
Kód: Egész kijelölése
/*
MPL115A1 sparkfun breakout baropressure meter
SDN : pin 7
CSN : pin 10
SDI/MOSI : pin 11
SDO/MISO : pin 12
SCK : pin 13
*/
// the sensor communicates using SPI, so include the library:
#include <SPI.h>
#define PRESH 0x80
#define PRESL 0x82
#define TEMPH 0x84
#define TEMPL 0x86
#define A0MSB 0x88
#define A0LSB 0x8A
#define B1MSB 0x8C
#define B1LSB 0x8E
#define B2MSB 0x90
#define B2LSB 0x92
#define C12MSB 0x94
#define C12LSB 0x96
#define CONVERT 0x24
#define chipSelectPin 10
#define shutDown 7
float A0_;
float B1_;
float B2_;
float C12_;
void setup() {
Serial.begin(115200);
// start the SPI library:
SPI.begin();
// initalize the data ready and chip select pins:
pinMode(shutDown, OUTPUT);
digitalWrite(shutDown, HIGH);
pinMode(chipSelectPin, OUTPUT);
digitalWrite(chipSelectPin, HIGH);
delay (10);
// read registers that contain the chip-unique parameters to do the math
unsigned int A0H = readRegister(A0MSB);
unsigned int A0L = readRegister(A0LSB);
A0_ = (A0H << 5) + (A0L >> 3) + (A0L & 0x07) / 8.0;
unsigned int B1H = readRegister(B1MSB);
unsigned int B1L = readRegister(B1LSB);
B1_ = ( ( ( (B1H & 0x1F) * 0x100)+B1L) / 8192.0) - 3 ;
unsigned int B2H = readRegister(B2MSB);
unsigned int B2L = readRegister(B2LSB);
B2_ = ( ( ( (B2H - 0x80) << 8) + B2L) / 16384.0 ) - 2 ;
unsigned int C12H = readRegister(C12MSB);
unsigned int C12L = readRegister(C12LSB);
C12_ = ( ( ( C12H * 0x100 ) + C12L) / 16777216.0 ) ;
}
void loop() {
Serial.print("de druk is : ");
Serial.println(baropPessure());
delay(1000);
}
//Read registers
unsigned int readRegister(byte thisRegister ) {
unsigned int result = 0; // result to return
digitalWrite(chipSelectPin, LOW);
delay(10);
SPI.transfer(thisRegister);
result = SPI.transfer(0x00);
digitalWrite(chipSelectPin, HIGH);
return(result);
}
//read pressure
float baropPessure(){
digitalWrite(chipSelectPin, LOW);
delay(3);
SPI.transfer(0x24);
SPI.transfer(0x00);
digitalWrite(chipSelectPin, HIGH);
delay(3);
digitalWrite(chipSelectPin, LOW);
SPI.transfer(PRESH);
unsigned int presH = SPI.transfer(0x00);
delay(3);
SPI.transfer(PRESL);
unsigned int presL = SPI.transfer(0x00);
delay(3);
SPI.transfer(TEMPH);
unsigned int tempH = SPI.transfer(0x00);
delay(3);
SPI.transfer(TEMPL);
unsigned int tempL = SPI.transfer(0x00);
delay(3);
SPI.transfer(0x00);
delay(3);
digitalWrite(chipSelectPin, HIGH);
unsigned long press = ((presH *256) + presL)/64;
unsigned long temp = ((tempH *256) + tempL)/64;
float pressure = A0_+(B1_+C12_*temp)*press+B2_*temp;
float preskPa = pressure* (65.0/1023.0)+50.0;
return(preskPa);
}
Kösz. Megnéztem, kipróbáltam.
Leegyszerűsítettem, hogy csak kettő beolvasást csináltam.
A nagyobb helyiérték nulla nyomásnál 7, az alacsonyabb byte pedig 100 körül ingadozik.
Az, hogy 100 körül ingadozik, azt megértem, hiszen 400Pa nyomás méréshatára, ami elég kicsi.
De hogy a magasabb byte miért 7-el indít, azt nem értem.
ha szívást eresztek az érzékelőre, akkor 0 lesz az értéke.
Már arra gondoltam, hogy valami számábrázolási gond lehet, de hát a 7 az a 6 bit 64-ének sehogy nem a fele, meg aztán unsigned int a deklarálása, az meg nem olyan.
most ott tartok, hogy csinálok egy mérés előtti kalibrációt, és a nullát azt korrigálom.
Összeállítok egy referencia mérést, hogy a végértékről legyen valami fogalmam.
Ha valaki ehhez a 7-es induló értékhez tud valami okosat mondani, azt megköszönném.
Csaba
Leegyszerűsítettem, hogy csak kettő beolvasást csináltam.
A nagyobb helyiérték nulla nyomásnál 7, az alacsonyabb byte pedig 100 körül ingadozik.
Az, hogy 100 körül ingadozik, azt megértem, hiszen 400Pa nyomás méréshatára, ami elég kicsi.
De hogy a magasabb byte miért 7-el indít, azt nem értem.
ha szívást eresztek az érzékelőre, akkor 0 lesz az értéke.
Már arra gondoltam, hogy valami számábrázolási gond lehet, de hát a 7 az a 6 bit 64-ének sehogy nem a fele, meg aztán unsigned int a deklarálása, az meg nem olyan.
most ott tartok, hogy csinálok egy mérés előtti kalibrációt, és a nullát azt korrigálom.
Összeállítok egy referencia mérést, hogy a végértékről legyen valami fogalmam.
Ha valaki ehhez a 7-es induló értékhez tud valami okosat mondani, azt megköszönném.
Csaba