PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : ATmega88 mit Nunchuk WII - Rückgabewert immer 0xFF



Minkfeld
04.12.2009, 12:39
Hallo zusammen,

Ich habe jetzt schon ein paar nette Projekte mit nem Nunchuk +
Controller gesehen und hab mich gestern mal dran gemacht meinen
umzubauen.

Hardware: STK500 + ATMega88 + JTAGICEmkII + 8MHz Quarz
Betriebsspannung: 3,3V
Verbindungen: SDA(PC4) an Grüne Leitung Nunchuk mit 2,2kOhm Pullup
SCL(PC5) an Gelbe Leitung Nunchuk mit 2,2kOhm Pullup

Software in Anhang.

Prinzipiell scheint die TWI Kommunikation zu funktionieren. Jedoch
bekomm ich bei allen 6 Bytes immer nur 0xff als Wert zurück. Hab gelesen
dass dieses Problem schon mehrere Leute hatten, jedoch ne genaue Ursache
konnte keiner nennen.


Hat einer ne Idee was der Fehler sein könnte?


Gruß,
Mink



//************************************************** ***************************
//* Project: ATMega88 + WII Nunchuk *
//* Version: beta *
//* File: device.c *
//* Target MCU: ATMega88 *
//* Compiler: GCC *
//* Simulator: AVRStudio 4.17 *
//* Emulator: JTAG ICE MKII *
//* Author: Minkfeld *
//* Date: 03.12.09 *
//************************************************** ***************************

#include <stdio.h>
#include <avr/interrupt.h>

#include "General.h"
#include "Delay.h"
#include "TWI_Master.h"

unsigned int Data[8];
unsigned int test_buffer[100];
unsigned int buffer_count;

int main(void)
{
uint8_t i;

uint8_t SlaveAddress = 0x52;

DDRD = 0x08;

//init TWI Master interface with bitrate of 100000Hz
if (!TWIM_Init (100000))
{
while (1);
{
;
}
}

//do a handshake with the nunchuk
(TWIM_Start (SlaveAddress, TWIM_WRITE));
TWIM_Write (0x40);
TWIM_Write (0x00);
Delay_ms (200);
TWIM_Stop ();

//main loop
while (1)
{

//read 6 bytes from nunchuck
if (!TWIM_Start ((SlaveAddress), TWIM_READ))
{
TWIM_Stop ();
}

else
{
for (i=0;i<5;i++)
{
Data[i] = TWIM_ReadAck();
buffer_count++;
test_buffer[buffer_count] = Data[i];
}

Data[5] = TWIM_ReadNack();
buffer_count++;
test_buffer[buffer_count] = Data[5];
TOOGLE_BIT(PORTD,3);
TWIM_Stop ();
}



//write byte to request next data from the nunchuck
if (!TWIM_Start (SlaveAddress, TWIM_WRITE))
{
TWIM_Stop ();
}

else
{
TWIM_Write (0x00);
Delay_ms (200);
TWIM_Stop ();
}
}
}

m.a.r.v.i.n
04.12.2009, 17:15
Hallo Mink,

ist das ein Original WII Nunchuk oder ein Nachbau? Bei den Nachbauten kann man sich nicht auf die Drahtfarben verlassen. Evtl. mal am abgeschnittenen Stecker duchklingeln. Hier ist die Pinbelegung (http://www.cc-zwei.de/wiki/index.php/Wii-Nunchuk_Hintergrundwissen)

Was mir am deinem Programm auffällt, sind die 200ms Delay vor dem Stop Befehl. Die Delays sollten hinter den Stop Befehl stehen.

radbruch
04.12.2009, 17:56
Hallo

Bei meinen Versuchen funktionierte die Slave-Adresse nicht:

'Const Nunchuck_write = &H52 ' Slaveadresse
'Const Nunchuck_read = &H53
Const Nunchuck_write = &HA4 ' Slaveadresse
Const Nunchuck_read = &HA5


Bas_com: https://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=389524#389524

C: https://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=390124#390124

Ergebnissbytes umrechnen: https://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=389925#389925

Viel Erfolg

mic

RoboTido
10.02.2010, 20:12
Hallo,

ich beschäftige mich seit mehreren Tagen damit, eine Kommunikation mit einer Controllerschaltung (ATmega168) in C zu implementieren, um einen kleinen Roboter damit zu steuern. Das Gros läuft eigentlich schon, aber der Nunchuk sendet mir stets 6x 0xFF zurück.

Was ich mache:

1) 86ms nach dem Start sende ich mit Adresse 0x52: 0x40, 0x00. Auf alle Bytes erhalte ich ein ACK. Pause: 48ms

2) Danach lese ich ebenfalls unter 0x52 und erhalte 6x 0xFF. Pause: ca. 2,8ms

3) Dann sende ich unter Adr. 0x52 eine 0x00 (, um wieder Adresse 0x00 auszuwählen). Pause: 17,8ms

Danach wiederholen sich Schritte 2) und 3) kontinuierlich.


Ich weiß langsam nicht mehr, wo ich den Fehler suchen soll....
- Gibt es hinsichtlich des Timings der einzelnen Pakete etwas zu beachten?
- Hat jemand noch eine Idee, warum der Nunchuk immer nur mit 0xFF antwortet?
- Wenn ich unter 3) Adresse 0x20 auswähle (wo die Kalibrierungsdaten liegen sollten, erhalte ich ebenfalls nur 0xFFs...


Das verzwickte daran ist:
Die Software für das ATM18 Projekt (http://www.cc-zwei.de/wiki/index.php/ATM18::Projekt::Wii-Nunchuk) läuft auf meiner Hardware zwar problemlos, jedoch ist mir die Updaterate zu klein.... (daher arbeite ich gerade an dieser Neu-Implementation...)

Gruß und vielen Dank im Voraus,
Tido

Jaecko
10.02.2010, 20:36
Stell mal die Software rein; da sieht man mehr als bei ner Beschreibung. Bei mir rennt der Nunchuk perfekt. Ein "Fehler" ist, wenn man z.B. den Bus mit 400 kHz rennen lässt. Da hängt der sich bei mir immer auf. 100 kHz reichen.

RoboTido
10.02.2010, 20:59
Bei mir rennt der Bus auch bei 100 KHz. Beim CC2 Projekt waren das sogar noch weniger....

Arkon
07.04.2012, 18:18
*staubwisch*

Moin,
ich adoptiere diesen Thread mal, da es bei mir das gleiche Problem gibt:

Ich betreibe einen ATMega32 direkt mit 3V3, da ich keinen Levelshifter zur Hand habe, und der Eigenbau scheinbar fehlerhaft funktionierte (keine Verbindung zum Nunchuk möglich). Zur Kommunikation nutze ich die I2C-Lib von Peter Fleury. Da ich leider grade kein LCD oder eine Möglichkeit habe die Daten an den PC zu senden toggel ich zwei LEDs um die Funktion zu testen.

Die Initialisierung läuft durch, und auch die Daten werden angefordert und empfangen. Für einen ersten Funktionstest wollte ich mit einer der Tasten eine LED schalten. Doch diese ist nach dem ersten Auslesen des Nunchuks dauerhaft an. Auch die anderen Bits sind alle 1.

Auch das dekodieren mit
x = (x^0x17) + 0x17 brachte keine Besserung. Zudem lese ich häufiger, dass der Nunchuk die Adresse 0x52 haben soll. Damit bleibt aber die Kommunikation stehen.

Ein Lösungsansatz ist, die TWI-Geschwindigkeit zu reduzieren. Diese Möglichkeit bietet die Lib von Peter aber in den Dateien i2cmaster.h und i2cmaster.c nicht. Wenn ich die anstatt der i2cmaster.c aber die twimaster.c in mein Projekt (AVR Studio4) einbinde bietet sich diese Möglichkeit aber die Kommunikation kommt nicht mehr zu Stande.

Hat jemand einen Tipp oder gar einen Lösungsansatz für mein Problem?



//#define F_CPU 8000000L


#include <avr/io.h>
#include <stdio.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include "i2cmaster.h"

#define NC_ADRESS 0xA4
#define LED1_AN PORTD |= (1<<PD4)
#define LED1_AUS PORTD &= ~(1<<PD4)
#define LED1_TOG PORTD ^= (1<<PD4)
#define LED2_AN PORTD |= (1<<PD5)
#define LED2_AUS PORTD &= ~(1<<PD5)
#define LED2_TOG PORTD ^= (1<<PD5)

int send_zero()
{
i2c_start_wait(NC_ADRESS + I2C_WRITE);
i2c_write(0x00);
i2c_stop();
}

int main(void)
{
uint8_t nc_data[6], btnc, btnz, temp;
uint16_t accx, accy, accz;
uint8_t i=0;

// Daten-Array leeren
for(int i=0; i<4 ; i++)
{
nc_data[i] = 0;
}

sei();


for(i=0; i<4 ; i++)
{
LED1_TOG;
_delay_ms(500);
}

i2c_init();

// Nunchuk initialisieren
i2c_start_wait(NC_ADRESS + I2C_WRITE);
i2c_write(0x40);
i2c_write(0x00);
i2c_stop();

while(1)
{
LED1_AN;
_delay_ms(100);


send_zero();


i2c_rep_start(NC_ADRESS + I2C_READ);

for(i=0; i<6 ; i++)
{
nc_data[i] = i2c_readAck();
_delay_us(100);
}
i2c_stop();


LED1_AUS;
_delay_ms(500);


for(i=0; i<6 ; i++)
{
nc_data[i] = (nc_data[i] ^ 0x17) + 0x17;
}


if((nc_data[5] >> 0) & 1)
{
LED2_AN;
}
else
{
LED2_AUS;
}
}


return 0;

}