mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Nunchuk-Problem - komische Werte


Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!
Ich hoffe, einer von Euch kann mir sagen wo ich hier den Denkfehler 
habe.. Ich glaube, dass ich bei dem Auslesen der Bytes aus den Registern 
einen Fehler mache in Routine getnunchuk().
Es ist aber richtig, dass in einem Register 16Bytes enthalten sind, ja?? 
Hatte bisher über I²C immer nur ein Byte pro Register.
Naja. Jedenfalls kann ich schon erkennen, on die Tasten gedrückt werden. 
Mehr jedoch nicht..

Das hier ist mein Code für einen ATMEGA88P


#define F_CPU 18432000L
#define myBRR0 9   //115200 bps 18.432MHz

#include <avr/io.h>
#include <stdint.h>
#include <stdlib.h>
#include <inttypes.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include <avr/delay.h>



unsigned char buffer[10];
long data=0;

//Routinen
void uart_init(void)
{
    UBRR0H = (unsigned char)(myBRR0 >> 8);
      UBRR0L = (unsigned char)myBRR0;  
    UCSR0B = (1<<TXEN0);
    UCSR0C = (1<<UCSZ01)|(1<<UCSZ00); // 8data, 1stopbit   
}


void uart_send(unsigned char data)
{
  while (!(UCSR0A & (1<<UDRE0)) );
  UDR0 = data;
}

  


void uart_send_string(char *datastring)
{
   for (;*datastring !='\0';datastring++)
  {    
    loop_until_bit_is_set (UCSR0A, UDRE0);  
    UDR0=*datastring;
  }   
}


void twi_init(void)
{
  PRR&=0x7F;
  TWBR=84;                                    //SCL=100@ Prescaler 1,
  TWSR&=0xFC;
  TWCR=0x04;                                          //Kein Interrupt; TWI aktivieren 0000 0100
}

void twi_transmit(char address, char reg, char data)//Subroutine fuer Datenuebertragung
{
  TWCR = 0xA4;                                // Start 1010 0100 TWINT, TWSTA, TWEN high
  while(!(TWCR & 0x80));                      // warten bis die TWINT low ist, heisst Transmission fertig 
  TWDR = address;                             // Adresse vom Sensor laden
  TWCR = 0x84;                                // Transmission anfangen (TWINT auf high setzen)
  while(!(TWCR & 0x80));                      // warten bis die TWINT low ist, heisst Transmission fertig
  TWDR = reg;                                 // Register Nr. laden
  TWCR = 0x84;                                // Transmission anfangen (TWINT auf high setzen)
  while(!(TWCR & 0x80));                      // warten bis die TWINT low ist, heisst Transmission fertig
  TWDR = data;                                // Befehl fuer Art der Messung laden
  TWCR = 0x84;                                // Transmissuion anfangen (TWINT auf high setzen)
  while(!(TWCR & 0x80));                      // warten bis die TWINT low ist, heisst Transmission fertig
  TWCR = 0x94;                                // Stopp 1001 0100 TWINT, TWSTO, TWEN high

}

void get_nunchuk(char address, char reg)       //Subroutine fuer Datenempfang
{
unsigned int read_data[16];

   TWCR = 0xA4;                                     // Start 1010 0100 TWINT, TWSTA, TWEN high
   while(!(TWCR & 0x80));                           // warten bis die TWINT low ist, heisst Transmission fertig  
   TWDR = address;                                  // Adresse vom Sensor laden
   TWCR = 0x84;                                     // Transmission anfangen (TWINT auf high setzen)
   while(!(TWCR & 0x80));                           // warten bis die TWINT low ist, heisst Transmission fertig 
   TWDR = reg;                                      // Register Nr. laden, von dem gelesen werden soll
   TWCR = 0x84;                                     // Transmission anfangen (TWINT auf high setzen)
   while(!(TWCR & 0x80));                           // warten bis die TWINT low ist, heisst Transmission fertig 

 for (int row=0;row<16;row++)
{  
   TWCR = 0xA4;                                     // Start 1010 0100 TWINT, TWSTA, TWEN high (repeated start)
   while(!(TWCR & 0x80));                           // warten bis die TWINT low ist, heisst Transmission fertig 
   TWDR = address+1;                                // Adresse vom Sensor mit Read bit laden (SLA+R)
   TWCR = 0xC4;                                     // Transmission anfangen ( TWINT high TWEA high)
   while(!(TWCR & 0x80));                           // warten bis die TWINT low ist, heisst Transmission fertig 
   TWCR = 0x84;                                     // Transmission anfangen mit NACK (TWINT auf high setzen TWEA low)
   while(!(TWCR & 0x80));                           // warten bis die TWINT low ist, heisst Transmission fertig 
   read_data[row] = TWDR;                           // Messergebniss in die Variable speichern
   
}

   TWCR = 0x94;                                     // Stopp 1001 0100 TWINT, TWSTO, TWEN high


   for (int i=0;i<16;i++)
  {
    read_data[i]  = ((read_data[i]^0x17)+0x17);         //XOR-Verschlüsselung
    uart_send_string(itoa(read_data[i],buffer,10));           //Wert übermitteln
    uart_send_string(",");
  }  

}





int main(void)
{
  OSCCAL=0x9f;
  uart_init();
  
  uart_send(0x0C);
    twi_init();

  DDRD |= (1<<PD1)|(1<<PD2);
  sei();    // Enable Interrupts

  twi_transmit(0xA4, 0x40, 0x00);
  _delay_ms(1);



   while(1)
   {
    
    uart_send_string("$Nunchuk,");
    get_nunchuk(0xA4, 0x00);

    uart_send(0x0D);
    uart_send(0x0A);
  

  }

return 0;
}

Im Leerlauf bekomme ich folgendes:
$Nunchuk,255,256,255,256,255,256,255,256,255,256,255,259,255,256,255,256 
,

drücke ich die Tasten kommt sowas hier:
$Nunchuk,255,256,255,256,255,256,255,256,255,256,255,256,255,256,255,256 
,
                                                     ***
Ansonsten ändert sich absolut nichts :-(
Ich kann auch Register 20 auslesen und bekomme da viele 
untgerschiedliche Werte.. Also das abfangen der Bytes scheint ja doch 
irgendwie zu klappen, aber es ist der Wurm drin...

Autor: Peter Z. (hangloose)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bei mir funktionierte es so... vielleicht hilfts ja


//------------------------------------------------------------------------------
//         Nunchuck Initialisieren
//------------------------------------------------------------------------------
void Wii_Controller_init(void)
{

i2c_start();
i2c_write(0xa4); 
i2c_write(0x40);
i2c_write(0x00);
i2c_stop();
    
}

//------------------------------------------------------------------------------
//         Wii "Nunchuck" und "Classic Controller" Daten decodieren
//------------------------------------------------------------------------------
unsigned char Wii_Controller_decode_byte (unsigned char x)
{
x = (x ^ 0x17) + 0x17;
return x;
}

//------------------------------------------------------------------------------
//         Wii Nunchuck und Classic Controller Auslesen
//------------------------------------------------------------------------------
void Wii_Controller_read(void)
{

char x;

i2c_start();
i2c_write(0xa4); 
i2c_write(0x00);
i2c_stop();
      
i2c_start();
i2c_write(0xa4); 
i2c_start();
i2c_write(0xa4 | 1);

i2c_tx[0]=i2c_read(1);
i2c_tx[1]=i2c_read(1);
i2c_tx[2]=i2c_read(1);
i2c_tx[3]=i2c_read(1);
i2c_tx[4]=i2c_read(1);
i2c_tx[5]=i2c_read(0);        
i2c_stop();
        
//Daten Decodieren
for(x=0;x<6;x++){
    i2c_tx[x]=Wii_Controller_decode_byte(i2c_tx[x]);
        
}

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo.. Ich weiß leider nicht wie Deine Routinen aussehen,die du 
aufrufst.warum meins  nicht geht konnte ich noch nicht klären.hab auch 
schon ein zweites nunchuk getestet und es hilft nix.

Autor: Peter Z. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Software I2C Routinen sind vom Codevision Compiler. Spielt aber auch 
nicht wirklich eine Rolle. Du siehst doch im Code was du senden und 
empfangen musst...

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aber ist es richtig so viele Bytes ohne repeatet Start zu empfangen? Und 
vor dem adresse+R noch ein adresse+W senden?? Ist das vom Nunchuk 
gefordert?

Autor: Stefan (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hi!
So, ich hatte ja etwas Zeit seitdem es geklappt hat und ich habe mal das 
Original-Nunchuk mit dem Nachbau (ebay 7€) verglichen... sind in dem 
Nachbau Quecksilberschalter drin??? :-)   Naja, zumindest ist die 
Auflösung nicht wirklich vergleichbar mit dem Original.
Habt ihr da ähniche Erfahrungen gemacht?? Oder gibt es da 
unterschiedliche Modelle?
Zur Messung: Aufzeichnung mit Matlab, Drehung frei Hand, aber die 
Ausbrüche bei dem Nachbau liegen nicht unbedingt an der Bewegung (siehe 
Original).

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.