Pages: [1]   Go Down
Author Topic: Cold Boot vs Reset  (Read 1170 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 71
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Dear All,
In a previous thread, you helped me build a small "headtracker" using the Wii Motion Plus.

More info is here:
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1267111521

I got my WM+ working,
driving two Servos that mimic the head movements of the "controller".

My code is here
-> http://www.jimboproductions.be/server/projects/tuning_people_bots

Anyway, I have a new problem
-> Whenever I plug in the power (or usb) to a Arduino and let it "cold boot",
the Wii Motion Plus does not return any useful data.

I have to reset the Arduino first,
after that everything runs like a charm.

I don't get this.
Cold boot or not, shouldn't the Atmega be doing the exact same thing?

I tought that maybe the WM+ had some sort of start up delay after the power came on. But even when I inserted a 10 second delay as the first line in my setup code, the same thing happened.

Anyone got any explanation for that?

Cheers,
Jim
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 71
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Also, a quick print of my latest code:

Quote
//Trapezoid or Runge-kutta 4th order integration program of wm+

#include <Streaming.h>
#include <Wire.h>
#include <Servo.h>

Servo yawServo;
Servo pitchServo;

int yawServoVal;
int pitchServoVal;

#define steps_per_deg_slow 20
#define steps_per_deg_fast 4

byte data[6];          //six data bytes
int yaw, pitch, roll;  //three axes
int yaw0, pitch0, roll0;  //calibration zeroes
int time, last_time;
float delta_t;
int last_yaw[3], last_pitch[3], last_roll[3];
float yaw_deg, pitch_deg, roll_deg;
int yaw_deg2, pitch_deg2, roll_deg2;
int startTag=0xDEAD;
int accel_x_axis, accel_y_axis, accel_z_axis;

void wmpOn(){
  Wire.beginTransmission(0x53);    //WM+ starts out deactivated at address 0x53
  Wire.send(0xfe);                 //send 0x04 to address 0xFE to activate WM+
  Wire.send(0x04);
  Wire.endTransmission();          //WM+ jumps to address 0x52 and is now active
}

void wmpSendZero(){
  Wire.beginTransmission(0x52);    //now at address 0x52
  Wire.send(0x00);                 //send zero to signal we want info
  Wire.endTransmission();
}

void calibrateZeroes(){
  for (int i=0;i<10;i++){
    wmpSendZero();
    Wire.requestFrom(0x52,6);
    for (int i=0;i<6;i++){
      data=Wire.receive();
    }
    yaw0+=(((data[3]>>2)<<smiley-cool+data[0])/10;        //average 10 readings for each zero
    pitch0+=(((data[4]>>2)<<smiley-cool+data[1])/10;
    roll0+=(((data[5]>>2)<<smiley-cool+data[2])/10;
  }
  Serial.print("Yaw0:");
  Serial.print(yaw0);
  Serial.print("  Pitch0:");
  Serial.print(pitch0);
  Serial.print("  Roll0:");
  Serial.println(roll0);
}

void receiveData(){
  wmpSendZero();                   //send zero before each request (same as nunchuck)
  Wire.requestFrom(0x52,6);        //request the six bytes from the WM+
  for (int i=0;i<6;i++){
    data=Wire.receive();
  }
  if(bitRead(data[3], 1)==1) yaw=(((data[3]>>2)<<smiley-cool+data[0]-yaw0)/steps_per_deg_slow;        //see http://wiibrew.org/wiki/Wiimote/Extension_Controllers#Wii_Motion_Plus
  else yaw=(((data[3]>>2)<<smiley-cool+data[0]-yaw0)/steps_per_deg_fast;
  if(bitRead(data[3], 0)==1) pitch=(((data[4]>>2)<<smiley-cool+data[1]-pitch0)/steps_per_deg_slow;    //for info on what each byte represents
  else pitch=(((data[4]>>2)<<smiley-cool+data[1]-pitch0)/steps_per_deg_fast;
  if(bitRead(data[4], 1)==1) roll=(((data[5]>>2)<<smiley-cool+data[2]-roll0)/steps_per_deg_slow;
  else roll=(((data[5]>>2)<<smiley-cool+data[2]-roll0)/steps_per_deg_fast;
}

float trapIntegrate(int y2, int y1, float deltax){
  float area=0;
  area=(y2+y1)/2*deltax/1000;
  return area;
}

float rk4Integrate(int y4, int y3, int y2, int y1, float deltax){
  float area=0;
  area=((y4+2*y3+2*y2+y1)/6)*deltax/1000;
  return area;
}

void setup()
  {
  Serial.begin(115200);
  Serial.println("WM+ Tuning People Bot Control");
  Wire.begin();
  wmpOn();                        //turn WM+ on
  calibrateZeroes();              //calibrate zeroes
  delay(1000);
  
  yawServo.attach(2);
  pitchServo.attach(3);
  pinMode(4, INPUT);
  }

void loop(){
  receiveData();                  //receive data and calculate yaw pitch and roll
  time=millis();
  delta_t=(time-last_time);
  
  /* Runge-kutta 4th Order Integration */
  yaw_deg+=rk4Integrate(yaw, last_yaw[0], last_yaw[1], last_yaw[2], delta_t);
  pitch_deg+=rk4Integrate(pitch, last_pitch[0], last_pitch[1], last_pitch[2], delta_t);
  roll_deg+=rk4Integrate(roll, last_roll[0], last_roll[1], last_roll[2], delta_t);
  last_yaw[2]=last_yaw[1];
  last_pitch[2]=last_pitch[1];
  last_roll[2]=last_roll[1];
  last_yaw[1]=last_yaw[0];
  last_pitch[1]=last_pitch[0];
  last_roll[1]=last_roll[0];
  last_yaw[0]=yaw;
  last_pitch[0]=pitch;
  last_roll[0]=roll;
  last_time=time;
  /* Runge-kutta 4th Order Integration */
  
  if (digitalRead(4) == 1)
    {
    last_yaw[2]=0;
    last_pitch[2]=0;
    last_roll[2]=0;
    last_yaw[1]=0;
    last_pitch[1]=0;
    last_roll[1]=0;
    last_yaw[0]=0;
    last_pitch[0]=0;
    last_roll[0]=0;
    yaw = 0;
    pitch = 0;
    roll = 0;
    yaw_deg = 0;
    pitch_deg = 0;
    roll_deg = 0;
    }

  yawServoVal = map(yaw_deg, -90, 90, 0, 179);
  if (yawServoVal < 0){yawServoVal = 0;};
  if (yawServoVal > 179){yawServoVal = 179;};
  yawServo.write(yawServoVal);
  
  pitchServoVal = map(pitch_deg, -90, 90, 0, 179);
  if (pitchServoVal < 60){pitchServoVal = 60;};
  if (pitchServoVal > 179){pitchServoVal = 179;};
  pitchServo.write(pitchServoVal);
  
  Serial<<yaw_deg<<"\t"<<pitch_deg<<"\t"<<roll_deg<<"\n";
  delay(10);
}
 


Logged

Chester, UK
Offline Offline
Sr. Member
****
Karma: 2
Posts: 489
Trying to return the love to none logic level MOSFETS
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Didn't think you could use delay in setup?
Logged

If your system involves lethal voltages/life critical/flamable elements - you probably shouldn't need to ask.
The Arduino != PC.

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 71
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I just think it's a function that runs once in the beginning of the program.
Logged

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 361
Posts: 17263
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Didn't think you could use delay in setup?

Sure you can, however if the purpose is to allow things to settle down before starting then it would be better if it's the very first statement in the setup() portion of your sketch.

Lefty
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 71
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I tried adding a 10 second delay at the beginning of the program.
Did not make a difference.
Logged

0
Offline Offline
Shannon Member
****
Karma: 200
Posts: 11730
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

There seem to be uninitialized variables in the sketch? - If so they will be sensitive to the (random) contents of RAM at startup - perhaps the sketch's setup() routine puts them in a saner state that allows it to run properly/better on the next reset. (Reset won't touch RAM I believe).

If you have a variable that can be read before it is first written, this is usually a problem.  In particular you have floats that are not initialized so they might be NaN's at startup - NaN's are contagious.
Logged

[ I won't respond to messages, use the forum please ]

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 71
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks Mark.
Updated my code to initialize all my variables before first run.
No difference.
Wierd Shit.

Quote
//Trapezoid or Runge-kutta 4th order integration program of wm+

#include <Streaming.h>
#include <Wire.h>
#include <Servo.h>

Servo yawServo;
Servo pitchServo;

int yawServoVal = 90;
int pitchServoVal = 90;

#define steps_per_deg_slow 20
#define steps_per_deg_fast 4

byte data[6] = {0,0,0,0,0,0};          //six data bytes
int yaw, pitch, roll = 0;  //three axes
int yaw0, pitch0, roll0 = 0;  //calibration zeroes
int time, last_time = 0;
float delta_t = 0;
int last_yaw[3] = {0, 0, 0};
int last_pitch[3] = {0,0,0};
int last_roll[3] = {0,0,0};
float yaw_deg, pitch_deg, roll_deg = 0;
int startTag=0xDEAD;

void wmpOn(){
  Wire.beginTransmission(0x53);    //WM+ starts out deactivated at address 0x53
  Wire.send(0xfe);                 //send 0x04 to address 0xFE to activate WM+
  Wire.send(0x04);
  Wire.endTransmission();          //WM+ jumps to address 0x52 and is now active
}

void wmpSendZero(){
  Wire.beginTransmission(0x52);    //now at address 0x52
  Wire.send(0x00);                 //send zero to signal we want info
  Wire.endTransmission();
}

void calibrateZeroes(){
  for (int i=0;i<10;i++){
    wmpSendZero();
    Wire.requestFrom(0x52,6);
    for (int i=0;i<6;i++){
      data=Wire.receive();
    }
    yaw0+=(((data[3]>>2)<<smiley-cool+data[0])/10;        //average 10 readings for each zero
    pitch0+=(((data[4]>>2)<<smiley-cool+data[1])/10;
    roll0+=(((data[5]>>2)<<smiley-cool+data[2])/10;
  }
  Serial.print("Yaw0:");
  Serial.print(yaw0);
  Serial.print("  Pitch0:");
  Serial.print(pitch0);
  Serial.print("  Roll0:");
  Serial.println(roll0);
}

void receiveData(){
  wmpSendZero();                   //send zero before each request (same as nunchuck)
  Wire.requestFrom(0x52,6);        //request the six bytes from the WM+
  for (int i=0;i<6;i++){
    data=Wire.receive();
  }
  if(bitRead(data[3], 1)==1) yaw=(((data[3]>>2)<<smiley-cool+data[0]-yaw0)/steps_per_deg_slow;        //see http://wiibrew.org/wiki/Wiimote/Extension_Controllers#Wii_Motion_Plus
  else yaw=(((data[3]>>2)<<smiley-cool+data[0]-yaw0)/steps_per_deg_fast;
  if(bitRead(data[3], 0)==1) pitch=(((data[4]>>2)<<smiley-cool+data[1]-pitch0)/steps_per_deg_slow;    //for info on what each byte represents
  else pitch=(((data[4]>>2)<<smiley-cool+data[1]-pitch0)/steps_per_deg_fast;
  if(bitRead(data[4], 1)==1) roll=(((data[5]>>2)<<smiley-cool+data[2]-roll0)/steps_per_deg_slow;
  else roll=(((data[5]>>2)<<smiley-cool+data[2]-roll0)/steps_per_deg_fast;
}


float rk4Integrate(int y4, int y3, int y2, int y1, float deltax){
  float area=0;
  area=((y4+2*y3+2*y2+y1)/6)*deltax/1000;
  return area;
}

void setup()
  {
  Serial.begin(115200);
  Serial.println("WM+ Tuning People Bot Control");
  Wire.begin();
  wmpOn();                        //turn WM+ on
  calibrateZeroes();              //calibrate zeroes
  delay(1000);
  
  yawServo.attach(2);
  pitchServo.attach(3);
  pinMode(4, INPUT);
  }

void loop(){
  receiveData();                  //receive data and calculate yaw pitch and roll
  time=millis();
  delta_t=(time-last_time);
  
  /* Runge-kutta 4th Order Integration */
  yaw_deg+=rk4Integrate(yaw, last_yaw[0], last_yaw[1], last_yaw[2], delta_t);
  pitch_deg+=rk4Integrate(pitch, last_pitch[0], last_pitch[1], last_pitch[2], delta_t);
  roll_deg+=rk4Integrate(roll, last_roll[0], last_roll[1], last_roll[2], delta_t);
  last_yaw[2]=last_yaw[1];
  last_pitch[2]=last_pitch[1];
  last_roll[2]=last_roll[1];
  last_yaw[1]=last_yaw[0];
  last_pitch[1]=last_pitch[0];
  last_roll[1]=last_roll[0];
  last_yaw[0]=yaw;
  last_pitch[0]=pitch;
  last_roll[0]=roll;
  last_time=time;
  /* Runge-kutta 4th Order Integration */
  
  if (digitalRead(4) == 1)
    {
    last_yaw[2]=0;
    last_pitch[2]=0;
    last_roll[2]=0;
    last_yaw[1]=0;
    last_pitch[1]=0;
    last_roll[1]=0;
    last_yaw[0]=0;
    last_pitch[0]=0;
    last_roll[0]=0;
    yaw = 0;
    pitch = 0;
    roll = 0;
    yaw_deg = 0;
    pitch_deg = 0;
    roll_deg = 0;
    }

  yawServoVal = map(yaw_deg, -90, 90, 0, 179);
  if (yawServoVal < 0){yawServoVal = 0;};
  if (yawServoVal > 179){yawServoVal = 179;};
  yawServo.write(yawServoVal);
  
  pitchServoVal = map(pitch_deg, -90, 90, 0, 179);
  if (pitchServoVal < 60){pitchServoVal = 60;};
  if (pitchServoVal > 179){pitchServoVal = 179;};
  pitchServo.write(pitchServoVal);
  
  Serial<<yaw_deg<<"\t"<<pitch_deg<<"\t"<<roll_deg<<"\n";
  delay(10);
}
 


Logged

UK
Offline Offline
Faraday Member
**
Karma: 17
Posts: 2884
Gorm deficient
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Can you use "Code" instead of "quote" when posting code, please?
My scroll finger is feeling poorly.
Logged

Per Arduino ad Astra

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 71
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm sorry. I was using "copy for discourse" in the Arduino IDE. I thought that was how it was to be done.

Anyone, any ideas so far?
Why does my Arduino act different on reset then when I power cycle it?
Logged

Phoenix, Arizona USA
Offline Offline
Faraday Member
**
Karma: 39
Posts: 5557
Where's the beer?
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

First off, let me say I know nothing about the Wii, Nunchuck, Motion+ or how to make it work with the Arduino (I do realize that the Motion+ and Nunchuck are separate, but work together) - with that said, I found this page:

http://www.windmeadow.com/node/42

I noticed that it's init function is different from your's; maybe the motion+ has a different init? Or do you have to do the init for the nunchuck and a different one for the motion+?

I am probably waaay off-base here...

 smiley

[edit]Hmm - looking at this page:

http://randomhacksofboredom.blogspot.com/2009/06/wii-motion-plus-arduino-love.html

seems to indicate that your code matches up - unless this is your site!  smiley-grin[/edit]

[edit]I guess what I am getting at is that maybe on cold-boot, something gets sent that partially inits the wiimotion, but not fully, then a reset throws some new values to finish the init...?

 :-?[/edit]
« Last Edit: March 04, 2010, 04:51:59 pm by keeper63@cox.net » Logged

I will not respond to Arduino help PM's from random forum users; if you have such a question, start a new topic thread.

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 71
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey Crosh,
Yeah, my code is 90% that of Nuckles.
Picked it up in a topic here.

I'm still baffeled about the whole thing.
Is there any information available about what exactly the Arduino does on a cold boot vs a reset?
Logged

Pages: [1]   Go Up
Jump to: