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
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 | }
|
> 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.
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?
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?
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.