Help with analogRead/Write

Hello

I'm having a lot of trouble understanding how this works.. I've tried running simple code like:

void setup() {
Serial.begin(9600);
}

void loop() {
analogWrite(3, 22);
Serial.println(analogRead(3));
}

But all my serial monitor prints is numbers flickering around 270.. I've also tried port 9-11 which should be PWM, same results.. I've tried on both my Uno and Mega 2560, same results... With and without shields.

The problem comes down to this, I'm building a robot, and have Sparkfun Joystick Shield and the following code:

const int PIN_BUTTON_SELECT = 2; // Select button is triggered when joystick is pressed
const int PIN_BUTTON_RIGHT = 3;
const int PIN_BUTTON_UP = 4;
const int PIN_BUTTON_DOWN = 5;
const int PIN_BUTTON_LEFT = 6;

const int PIN_ANALOG_X = A0;
const int PIN_ANALOG_Y = A1;

int LeftMotor;
int RightMotor;

int long x;
int long x1;
int long y;
int long y1;
int long f1;
int long r1;
int long r2;
int long magnitude;
int long theta;

const int M1 = 9; //RightMotor
const int M2 = 10; //LeftMotor

int ToM1;
int ToM2;

void setup() {
  Serial.begin(9600);
 
  digitalWrite(PIN_BUTTON_RIGHT, 1);
    
  digitalWrite(PIN_BUTTON_LEFT, 1);

  digitalWrite(PIN_BUTTON_UP, 1);
   
  digitalWrite(PIN_BUTTON_DOWN, 1);
   
  digitalWrite(PIN_BUTTON_SELECT, 1);  

  pinMode(M1, OUTPUT);
  pinMode(M2, OUTPUT);

}




void loop() {


  x = analogRead(PIN_ANALOG_X)-517;                             // Makes x = 0 when joystick is steady
  y = analogRead(PIN_ANALOG_Y)-511;                             // Makes y = 0 when joystick is steady

  magnitude = sqrt(sq(x)+sq(y));                                // Finds the magnitude of x and y

  double theta = atan2(y,x);                                    // Finds the angle (direction) of magnitude

  x1 = magnitude*cos(theta)/2+magnitude*sin(theta);             // The parameter for LeftMotor
  y1 = -magnitude*cos(theta)/2+magnitude*sin(theta);            // The parameter for RightMotor
  f1 = magnitude*sin(theta);                                    // Figures if we're going back or forward
  r1 = magnitude*cos(theta)/2-magnitude*sin(theta);             // The parameter for LeftMoter when reversing
  r2 = -magnitude*cos(theta)/2-magnitude*sin(theta);            // The parameter for RightMotor when reversing


  if (x1 > 500) {                                               // Gives LeftMotor an value from -500 to 500
      LeftMotor = 500;                                          // where 500 is full speed forward (clockwise)
    }                                                           // and -500 is full speed counterclockwise
    else if (-r1 < -500) {
      LeftMotor = -500;
    }
    else if (f1 < 0 and r1 < 0) {
      LeftMotor = r1;
    }
    else if (f1 < 0 and r1 > 0) {
      LeftMotor = -r1;
    }
    else {
      LeftMotor = x1;
  };



  if (y1 > 500) {                                               // Same for RightMotor
    RightMotor = 500;
    }
    else if (-r2 < -500) {
      RightMotor = -500;
    }
    else if (f1 < 0 and r2 < 0) {
      RightMotor = r2;
    }
    else if (f1 < 0 and r2 > 0) {
      RightMotor = -r2;
    }
    else {
      RightMotor = y1;
   };
                         
                                 
  ToM1 = map(RightMotor, -500, 500, 0, 255);                  // Gives Right and Left Motor a value
                                                              // from 0 to 255.
  ToM2 = map(LeftMotor, -500, 500, 0, 255);

  Serial.print("LM:");
  Serial.print(ToM2);
  Serial.print(" ");

  Serial.print("RM:");
  Serial.print(ToM1);
  Serial.print(" ");

  analogWrite(M1, ToM1);
  analogWrite(M2, ToM2); 

  Serial.print(analogRead(M1));
  Serial.print("   ");
  Serial.print(analogRead(M2));
  
  Serial.println();

  
}

But when reading the Serial Monitor i get 511 or so on the M1 read.. Changing ToM1 by moving joystick left and right (can see the change in the monitor) doesn't change the analogRead. But flicking the joystick up and down changes the value from 0 (down) to 1023 (up) so seems like it's hooked up to something else?
Just printing analogRead(11) gives the same result when moving the joystick but with more unstable numbers.. analogRead(M2) is also unstable, while M1 is stable?

Since I did the simple code, without it reading correct, I have no idea what to do?

What I need is having the ToM1 and ToM2 to outputs, so they can be wired to my Mega which got the motor control. The ToM1 and ToM2 reads works like they should.

Hope you can help me, cheers!
Martin Jakobsen

These are not the same pin:

analogWrite(3, 22);
Serial.println(analogRead(3));

An analogWrite to pin 3 is digital pin ~3.
An analogRead from pin 3 is analog pin 3 on the other edge of the board.

edit: I have always thought "analogWrite" is a crap name for a digital, albeit PWM, output.

'analogRead()' reads an analog pin (the pins marked A0..A5 on an Uno). 'analogWrite' writes a digital pin (the PWM pins).

So you're reading and writing different pins.

Okay thank you very much!
But I'm still not sure how to read/check if i get the right output at the digital PWM pin. How do I check that in the Serial Monitor?

I can see, when I use a volt meter that I it follows my ToM1 and 2, and everything acts as it should, but I would like to see it in the Serial Monitor if possible?

I don't know why, but if I run a Serial.print(digitalRead(M1)); or M2, the port changes to I/O, why is that when I don't write anything? when I remove the digitalRead, volt meter reads what it should, and with it running I read 0 or 1V depending on the joystick position?

Thanks again
Martin

MartinCalmar:
I don't know why, but if I run a Serial.print(digitalRead(M1)); or M2, the port changes to I/O, why is that when I don't write anything?

int digitalRead(uint8_t pin)
{
	uint8_t timer = digitalPinToTimer(pin);
	uint8_t bit = digitalPinToBitMask(pin);
	uint8_t port = digitalPinToPort(pin);

	if (port == NOT_A_PIN) return LOW;

	// If the pin that support PWM output, we need to turn it off
	// before getting a digital reading.
	if (timer != NOT_ON_TIMER) turnOffPWM(timer);

	if (*portInputRegister(port) & bit) return HIGH;
	return LOW;
}

So you use digitalRead and it kills your PWM you say. You see that third to the last line?