@Morpheus1997:
Die Adresse 60H muss in GCC als 0x60 angegeben werden.
@Morpheus1997:
Die Adresse 60H muss in GCC als 0x60 angegeben werden.
Gruß
Dirk
Hallo,
hm.. okay.. das bringt mich wenigstens schon mal einen schritt weiter. Allerdings hab ich nun das Beispielprogramm des Cmps03 mal wie folgt umgeschrieben:
Allerdings, das Ergebnis:Code:/* * **************************************************************************** * RP6 ROBOT SYSTEM - ROBOT BASE EXAMPLES * **************************************************************************** * Example: I2C Master - Hdmm01 Rp6 * Author(s): M.Hunfeld * **************************************************************************** * Description: * * This Example shows how to use the compass module Hdmm01 * with RP6Library. * * **************************************************************************** */ /*****************************************************************************/ // Includes: #include "RP6RobotBaseLib.h" // IMPORTANT: #include "RP6I2CmasterTWI.h" // Include the I²C-Bus Slave Library /*****************************************************************************/ // I2C Event handlers: /** * This function gets called automatically if there was an I2C Error like * the slave sent a "not acknowledge" (NACK, error codes e.g. 0x20 or 0x30). * The most common mistakes are: * - using the wrong address for the slave * - slave not active or not connected to the I2C-Bus * - too fast requests for a slower slave * Be sure to check this if you get I2C errors! */ void I2C_transmissionError(uint8_t errorState) { writeString_P("\nI2C ERROR --> TWI STATE IS: 0x"); writeInteger(errorState, HEX); writeChar('\n'); } /*****************************************************************************/ #define CMPS 0x60//Die Adresse des Hdmm01 Moduls #define Read 0x61//Die Adresse des Hdmm01 Moduls zum Lesen #define MEASURE_16_BIT 0x00//Die Register-Adresse uint16_t readCMPS(uint8_t datareg) {uint16_t result = 0xffff; uint8_t results[3]; I2CTWI_transmitByte(CMPS, datareg); if (datareg == MEASURE_16_BIT) { I2CTWI_readBytes(Read, results, 2); result = (results[0] << 8) + results[1]; } else { result = I2CTWI_readByte(Read); } return result; } void task_CMPS(void) {uint16_t degrees; if (getStopwatch1() > 500) { degrees = readCMPS(MEASURE_16_BIT); writeString_P("Richtung: "); writeIntegerLength((degrees / 10), DEC, 3); writeChar('.'); writeIntegerLength(degrees, DEC, 1); writeString_P(" Grad\n"); setStopwatch1(0); } } /*****************************************************************************/ // Main - The program starts here: int main(void) { initRobotBase(); I2CTWI_initMaster(100); // Initialize the TWI Module for Master operation // with 100kHz SCL Frequency // Register the event handlers: I2CTWI_setTransmissionErrorHandler(I2C_transmissionError); powerON(); startStopwatch1(); while(true) { task_I2CTWI(); task_RP6System(); task_CMPS(); } return 0; }
Es wird wahrscheinlich daran liegen, dass es bei dem Hdmm01 Modul nur ein Register gibt, welches man allerdings manipulieren muss. Malthy hat es in Bascom so gelöst:Code:I2C ERROR --> TWI STATE IS: 0x20 I2C ERROR --> TWI STATE IS: 0x48 Richtung: 000.0 Grad I2C ERROR --> TWI STATE IS: 0x20 I2C ERROR --> TWI STATE IS: 0x48 Richtung: 000.0 Grad
072.' sensor adressieren (schreiben)
073.I2cwbyte Cmp_w
074.' register adressieren
075.I2cwbyte &H00
076.'
077.' register manipulieren -> reset coil
078.I2cwbyte &B00000100
Doch wie realisiert man dies in "C", für die Rp6 Lib tauglich?
Liebe Grüße Marcel
Hi Marcel,
das Modul CMPS03 wird völlig anders ausgelesen als der HDMM01. Daher kannst du mein Programm nicht 1:1 nehmen.
Ich habe den HDMM01 nicht selbst. Du kannst folgendes Testprogramm mal als Anfang für eigene Experimente nehmen:
Ein Problem bei der Lesefunktion ist, dass an einer Stelle (siehe Kommentar) eigentlich kein Stop gesendet werden darf. Das macht aber die RP6 Library.Code:/* * **************************************************************************** * RP6 ROBOT SYSTEM - ROBOT BASE EXAMPLES * **************************************************************************** * Example: I2C Master - HDMM01 * Author(s): Dirk * **************************************************************************** * Description: * * This Example shows how to use the compass module HDMM01 * with RP6Library. * * **************************************************************************** */ /*****************************************************************************/ // Includes: #include "RP6RobotBaseLib.h" // IMPORTANT: #include "RP6I2CmasterTWI.h" // Include the I²C-Bus Slave Library /*****************************************************************************/ // I2C Event handlers: /** * This function gets called automatically if there was an I2C Error like * the slave sent a "not acknowledge" (NACK, error codes e.g. 0x20 or 0x30). * The most common mistakes are: * - using the wrong address for the slave * - slave not active or not connected to the I2C-Bus * - too fast requests for a slower slave * Be sure to check this if you get I2C errors! */ void I2C_transmissionError(uint8_t errorState) { writeString_P("\nI2C ERROR --> TWI STATE IS: 0x"); writeInteger(errorState, HEX); writeChar('\n'); } /*****************************************************************************/ /** * Write a long number (with specified base) to the UART. * * Example: * * // Write a hexadecimal number to the UART: * writeLong(0xAACC,16); * // Instead of 16 you can also write "HEX" as this is defined in the * // RP6uart.h : * writeLong(0xAACC, HEX); * // Other Formats: * writeLong(1024,DEC); // Decimal * writeLong(044,OCT); // Octal * writeLong(0b11010111,BIN); // Binary */ void writeLong(int32_t number, uint8_t base) {char buffer[33]; ltoa(number, &buffer[0], base); writeString(&buffer[0]); } /*****************************************************************************/ // The I2C slave address of the compass module HDMM01 is 0x60: #define HDMM01_ADR 0x60 // HDMM01 Data Register: #define DATA_REG 0 // HDMM01 Commands: #define SET_COIL 0b00000010 #define RESET_COIL 0b00000100 #define MEASURE 0b00000001 uint8_t results[5]; /** * READ HDMM01 DATA REGISTER * * This function reads the data register of the HDMM01. * */ void readHDMM01(void) { I2CTWI_transmit2Bytes(HDMM01_ADR, DATA_REG, SET_COIL); mSleep(1); I2CTWI_transmit2Bytes(HDMM01_ADR, DATA_REG, RESET_COIL); mSleep(5); I2CTWI_transmit2Bytes(HDMM01_ADR, DATA_REG, MEASURE); mSleep(5); I2CTWI_transmitByte(HDMM01_ADR, DATA_REG); // Hier sollte eigentlich kein Stop sein ... I2CTWI_readBytes(HDMM01_ADR, results, 5); return; } /** * HDMM01 TASK * * This is the HDMM01 task. * */ void task_HDMM01(void) {uint16_t X, Y; if (getStopwatch1() > 500) { readHDMM01(); results[1] = results[1] & 0b00001111; results[3] = results[3] & 0b00001111; X = results[1] * 256; X = X + results[2]; Y = results[3] * 256; Y = Y + results[4]; writeString_P("XY: "); writeLong(X, DEC); writeChar(' '); writeLong(Y, DEC); writeString_P(" \n"); setStopwatch1(0); } } /*****************************************************************************/ // Main - The program starts here: int main(void) { initRobotBase(); I2CTWI_initMaster(100); // Initialize the TWI Module for Master operation // with 100kHz SCL Frequency // Register the event handlers: I2CTWI_setTransmissionErrorHandler(I2C_transmissionError); setLEDs(0b111111); mSleep(500); setLEDs(0b000000); powerON(); startStopwatch1(); while(true) { task_HDMM01(); task_I2CTWI(); task_RP6System(); } return 0; } /****************************************************************************** * Additional info * **************************************************************************** * Changelog: * - v. 1.0beta (initial release) 04.03.2012 by Dirk * * **************************************************************************** */ /*****************************************************************************/
Aber: Probier das doch erst einmal.
Gruß
Dirk
Hey Dirk,
vielen Dank schon mal für deine Bemühungen, aber leider ist bei diesem Programm das gleiche Problem: wieder dieser I2C ERROR...
Lg Marcel
Hey Morpheus1997,
vermutlich wirst Du nicht drumrumkommen, eine andere I²C Library, z.B. die von Peter Fleury, zu verwenden. Wir hatten mit einem anderen Sensor auch das Problem, dass die RP6Lib automatisch I²C Stops, Restarts oder Starts sendet, die für den Sensor nicht gesendet werden dürfen.
Natürlich kannst Du gerne noch weiter versuchen, vielleicht schaffst Du es ja doch noch. Vermutlich wirst Du aber schneller mit einer anderen Library Erfolg haben.
Viele Grüße
teamohnename
Geändert von teamohnename (05.03.2012 um 18:20 Uhr)
Hey Morpheus1997
nimm mal die aktuellste Lib vom rp6. Damit funktioniert es einwandfrei.
Die funktion zum einlesen des hdmm01 sieht dann einfach so aus :
#define hdmm01_address 0x60
void rbh_i2c_hdmm01( void )
{
unsigned char buf[ 5 ];
I2CTWI_transmit2Bytes( hdmm01_address, 0x00, 0b00000001 ); // take measurement
mSleep( 10 );
I2CTWI_transmitByte( hdmm01_address, 0x00 );
I2CTWI_readBytes( hdmm01_address, buf, 5 ); // read control - register + x , y - values
writeString_P("\nrbh_i2c_hdmm01: 0x");
writeInteger( buf[ 0 ], HEX);
writeChar(' ');
writeInteger( buf[ 1 ], HEX);
writeChar(' ');
writeInteger( buf[ 2 ], HEX);
writeChar(' ');
writeInteger( buf[ 3 ], HEX);
writeChar(' ');
writeInteger( buf[ 4], HEX);
writeChar(' ');
}
Viele Grüße
HSC123
Lesezeichen