Forum: Mikrocontroller und Digitale Elektronik Nunchuck auslesen - Problem


von Holger (Gast)


Lesenswert?

Hallo,

ich bin momentan dabei zu versuchen einen Nunchuck (schwarz) mit einem 
ATmega8L (3,3V, 8MHz) auszulesen. Nach allerlei gelösten Problemen, bin 
ich aber jetzt auf ein Problem gestoßen, dessen Lösung ich bisher nicht 
gefunden habe:

Ich schaffe es, die 6 Byte vom Nunchuck auszulesen, bekomme aber nur 
Werte für die beiden Buttons zurück, also Byte 6 ist je nach Betätigung 
der Buttons 0, 1, 2 oder 3. Die restlichen Bits und Bytes werden alle 
mit 0x00 zurückgegeben.

Möglicherweise habe ich den Nunchuck größtenteils geschrottet, da ich 
diesen zeitweise mit 5V versucht habe zu betreiben. Würde dann aber eher 
erwarten, dass ich entweder gar nichts, oder wenigstens auch noch den 
Joystick auslesen kann. Leider habe ich keine Wii, um dies testen zu 
können.
Ich betreibe den Nunchuck momentan direkt am ATmega, mit aktivierten 
internen Pull-ups. I2C Clock ist 100kHz, die Initialisierung findet mit 
dem Senden von 0xf0 0x55 0xfb 0x00 statt. Nach dem senden von 0x00 als 
Vorbereitung zum auslesen warte ich 50ms!? (bei kleineren Werten bekomme 
ich nur 0xff als Rückgabewerte).

Hatte jemand schon mal dieses Problem oder kann mir einen Hinweis zur 
Lösung geben?

Grüße,
Holger

von Holger (Gast)


Lesenswert?

Mein Code sieht folgendermaßen aus (Ausgabe werden auf einem LCD 
gemacht):
1
//#define F_CPU 8000000 // Toolchain->AVR/GNU C Compiler->Symbols
2
3
#include <avr/io.h>
4
#include <util/delay.h>
5
#include <util/twi.h>
6
#include "lcd.h"
7
#include <stdio.h>
8
9
#define SCL_CLOCK 100000UL
10
#define TW_ADDR_NUNCHUCK 0xA4
11
12
void twiWaitUntilTransmissionCompleted()
13
{
14
  while(!(TWCR & (1<<TWINT)));
15
}
16
17
void twiInit()
18
{
19
  TWSR = 0;                         // no prescaler 
20
  TWBR = ((F_CPU/SCL_CLOCK)-16)/2;  // must be > 10 for stable operation
21
}
22
23
uint8_t twiStart(uint8_t addr)
24
{
25
  TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
26
  twiWaitUntilTransmissionCompleted();
27
  if((TW_STATUS != TW_START) && (TW_STATUS != TW_REP_START)) return TW_STATUS;
28
  
29
  TWDR = addr;
30
  TWCR = (1<<TWINT) | (1<<TWEN);
31
  twiWaitUntilTransmissionCompleted();
32
  if((TW_STATUS != TW_MT_SLA_ACK) && (TW_STATUS != TW_MR_SLA_ACK)) return TW_STATUS;
33
  
34
  return 0;
35
}
36
37
uint8_t twiSendByte(uint8_t data)
38
{
39
  TWDR = data;
40
  TWCR = (1<<TWINT) | (1<<TWEN);
41
  twiWaitUntilTransmissionCompleted();
42
  if(TW_STATUS != TW_MT_DATA_ACK) return TW_STATUS;
43
  
44
  return 0;
45
}
46
47
uint8_t twiReadByteAck(uint8_t * data)
48
{
49
  TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
50
  twiWaitUntilTransmissionCompleted();
51
  if(TW_STATUS != TW_MR_DATA_ACK) return TW_STATUS;
52
  *data = TWDR;
53
  
54
  return 0;
55
}
56
57
uint8_t twiReadByteNack(uint8_t * data)
58
{
59
  TWCR = (1<<TWINT) | (1<<TWEN);
60
  twiWaitUntilTransmissionCompleted();
61
  if(TW_STATUS != TW_MR_DATA_NACK) return TW_STATUS;
62
  *data = TWDR;
63
  
64
  return 0;
65
}
66
67
bool twiStop()
68
{
69
  TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
70
71
  return true;
72
}
73
74
int main(void)
75
{
76
  DDRB = 0xFF; // Output
77
  PORTB = 0;
78
  DDRD = 0xFF; // Output
79
  PORTD = 0;
80
  DDRC &= ~((1<<PC4) | (1<<PC5));  // Input
81
  PORTC = (1<<PC4) | (1<<PC5);     // activate pull-ups
82
    
83
  lcd_init(LCD_DISP_ON);
84
  
85
  _delay_ms(200);
86
  
87
  twiInit();
88
  uint8_t r, s[6];
89
  char str[32];
90
  
91
  r = twiStart(TW_ADDR_NUNCHUCK+TW_WRITE);
92
  /*r = twiSendByte(0x40);
93
  r = twiSendByte(0x00);*/
94
  r = twiSendByte(0xf0);
95
  r = twiSendByte(0x55);
96
  r = twiSendByte(0xfb);
97
  r = twiSendByte(0x00);
98
  twiStop();
99
  _delay_ms(50);
100
  
101
  while (true)
102
  {
103
    r = twiStart(TW_ADDR_NUNCHUCK+TW_WRITE);
104
    r = twiSendByte(0x00);
105
    _delay_ms(50);
106
    r = twiStart(TW_ADDR_NUNCHUCK+TW_READ);
107
    _delay_ms(1);
108
    r = twiReadByteAck(&s[0]);
109
    r = twiReadByteAck(&s[1]);
110
    r = twiReadByteAck(&s[2]);
111
    r = twiReadByteAck(&s[3]);
112
    r = twiReadByteAck(&s[4]);
113
    r = twiReadByteNack(&s[5]);
114
    twiStop();
115
    sprintf(str, "%x %x %x %x\n%x %x %x", r, s[0], s[1], s[2], s[3], s[4], s[5]);
116
    lcd_clrscr();
117
    lcd_puts(str);
118
    _delay_ms(100);
119
  }
120
}

von Stefan F. (Gast)


Lesenswert?

> Möglicherweise habe ich den Nunchuck größtenteils geschrottet,
> da ich diesen zeitweise mit 5V versucht habe zu betreiben.

Sehr warscheinlich ist das der Fall.

Du solltest das Problem gezielt analysieren. In diesem Fall ist es am 
einfachsten, zuerst die Hardware zu verifizieren. Nämlich, indem du

a) einen anderen Nunchuck verwendest, oder
b) den Nunchuck an einer Wii benutzt.

Erst wenn du sicher bist, dass die Hardware heile ist, lohnt sich ein 
Blick in die Software.

von Holger (Gast)


Lesenswert?

So, ich hab mal einen anderen Nunchuck getestet, und dort hab ich genau 
das gleiche Problem: Taster kann ich auslesen, Joystick und 
Beschleunigungssensor geben nur 0 zurück :/
Die I2C-Bibliothek von Peter Fleury brachte auch keine Besserung.

Hat jemand eine Idee?

von Heisenberg (Gast)


Lesenswert?

Ich habe vor einiger Zeit einen Nunchuck in ein Projekt integriert.

Zum Ausprobieren habe ich einen China-Klon benutzt. Die 
Initialisierungssequenz hat interessanterweise nur mit dem Klon 
funktioniert, aber nicht mit einem Originalen von Nintendo.

Es gibt verscheidene Möglichkeiten das ding zum Reden zu bringen.
Aufgrund von wenig Zeit habe ich das dann damals(tm) nicht weiter 
verfolgt.

Möglicherweise führt sowas bei dir zu solchen Problemen?

von AD (Gast)


Lesenswert?

Heisenberg schrieb:
> Zum Ausprobieren habe ich einen China-Klon benutzt. Die
> Initialisierungssequenz hat interessanterweise nur mit dem Klon
> funktioniert, aber nicht mit einem Originalen von Nintendo.

Zu den Codes gibt es vielleicht bei den Homebrew-Programmierern 
aufklärung. Ich weiss das die China-Klone auch auf die Wii-Software 
anders reagieren. Beim USB loader GX z.B. spacken einige China-Klone 
rum. Bei den Spielen die ich kenne ist es aber kein Problem.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.