(edit sidebar)
Intro to Physical Computing Syllabus

Research & Learning

Other Class pages

Shop Admin

ITP Help Pages
Tom's pcomp site
DanO's pcomp site


Analog In with an Arduino

Labs.AnalogInScott2012Spring History

Hide minor edits - Show changes to output

Changed lines 121-122 from:
You know that the maximum input range of any analog input is from 0 to 5 volts.  So if you wanted to know the voltage on an analog input pin at any point, you use the map function to get it.
to:
You know that the maximum input range of any analog input is from 0 to 5 volts.  So if you wanted to know the voltage on an analog input pin at any point, you use a little math to get it.
Changed line 124 from:
// read the sensor:
to:
 // read the sensor:
Changed lines 127-128 from:
// using a floating point decimal variable (called a float):
float voltage = map(
analogValue, 0.0, 5.0);
to:
float voltage = (5./1023.)*analogValue;
Changed line 129 from:
Serial.println(voltage);
to:
Serial.println(voltage); 
Changed lines 185-204 from:
if(sensorValue<450){
digitalWrite(LEDone, HIGH);
digitalWrite(LEDtwo, LOW);

digitalWrite(LEDthree, LOW);
digitalWrite(LEDfour, LOW);
}else if (sensorValue >=450 && sensorValue<= 650){
digitalWrite(LEDone, HIGH);

digitalWrite(LEDtwo, HIGH);
digitalWrite(LEDthree, LOW);
digitalWrite(LEDfour, LOW);
}else if
(sensorValue >=651 && sensorValue<= 775){
digitalWrite(LEDone, HIGH
);
digitalWrite(LEDtwo, HIGH);
digitalWrite(LEDthree, HIGH);

digitalWrite(LEDfour, LOW);
}else if (sensorValue >=776){
digitalWrite(LEDone, HIGH);
digitalWrite(LEDtwo, HIGH);
digitalWrite(LEDthree, HIGH);

digitalWrite(LEDfour, HIGH);
to:
  if(sensorValue<450){
   digitalWrite(LEDone, HIGH);
    digitalWrite(LEDtwo, LOW);
   
digitalWrite(LEDthree, LOW);
   digitalWrite(LEDfour, LOW);
  }else if (sensorValue >=450 && sensorValue<= 650){
   
digitalWrite(LEDone, HIGH);
    digitalWrite(LEDtwo, HIGH);
   digitalWrite(LEDthree, LOW);
    digitalWrite(LEDfour, LOW);
  }else if (sensorValue >=651 && sensorValue<= 775){
    digitalWrite(LEDone, HIGH);
    digitalWrite(LEDtwo, HIGH);
    digitalWrite(LEDthree, HIGH);
    digitalWrite(LEDfour, LOW);
  }else if (sensorValue >=776){
    digitalWrite(LEDone, HIGH);
    digitalWrite(LEDtwo, HIGH);
    digitalWrite(LEDthree, HIGH);
    digitalWrite(LEDfour, HIGH);
  }
Deleted line 206:
}
Changed lines 110-111 from:
%lframe alt='Arduino with variable resistors and LED' hspace=10 width=300%[[Attach:arduino_fsrs_bb.png|Attach:arduino_fsrs_bb.png]]
%lframe alt='Arduino with variable resistors and LED schematic' hspace=10 width=300%[[Attach:arduino_fsrs_schem.png|Attach:arduino_fsrs_schem
.png]]
to:
%lframe alt='Arduino with variable resistors and LED' hspace=10 width=300%[[Attach:arduino_analogIn_digitalOut_bb.png|Attach:arduino_analogIn_digitalOut_bb.png]]
Deleted line 189:
Changed line 207 from:
(:sourceend:)
to:
(:sourceend:)
Changed lines 48-49 from:
First, establish some global variables: One to hold the value returned by the potentiometer, and another to hold the brightness value. Make a global constant to give the LED's pin number a name.
to:
First, establish some global variables: One to hold the value returned by the potentiometer; Make a global constants to give the LED's pin number a name as well as the sensor.
Added line 54:
const int potPin = 0;      // pin that the potentiometer is attached to
Deleted line 55:
int brightness = 0;        // PWM pin that the LED is on.
Changed lines 73-74 from:
In the main loop, read the analog value using analogRead() and put the result into the variable that holds the analog value.  Then divide the analog value by 4 to get it into a range from 0 to 255.  Then use the analogWrite() command to face the LED.  Then print out the brightness value.
to:
In the main loop, read the analog value using analogRead() and put the result into the variable that holds the analog value and print it out. Use the delay() command in conjunction with digitalWrite() to turn the LED on and off.
Changed lines 79-82 from:
   analogValue = analogRead(A0);      // read the pot value
    brightness = analogValue /4;      //divide by 4 to fit in a byte
    analogWrite(ledPin, brightness);
  // PWM the LED with the brightness value
 
  Serial.println(brightness);        // print the brightness value back to the serial monitor
to:
   analogValue = analogRead(potPin);      // read the pot value
    Serial.println(analogValue);        // print the value  of the pot back to the serial monitor
    digitalWrite(ledPin, HIGH);  // turn the LED on
   delay(analogValue);           // delay for a bit
    digitalWrite(ledPin, LOW);  // turn the LED off
    delay(analogValue);            // delay for a bit   
Changed lines 89-90 from:
When you run this code, the LED should dim up and down as you turn the pot, and the brightness value should show up in the serial monitor.
to:
When you run this code, the LED should blink faster and slower as you turn the pot, and the value should show up in the serial monitor.
Changed lines 93-94 from:
You can use many different types of variable resistors for analog input.  For example, the pink monkey in the photo below has his arms wired with flex sensors. These sensors change their resistance as they are flexed.  When the monkey's arms move up and down, the values of the flex sensors change the brightness of two LEDs.  The same values could be used to control servo motors, change the frequency on a speaker, or move servo motors. 
to:
You can use many different types of variable resistors for analog input.  For example, the pink monkey in the photo below has his arms wired with flex sensors. These sensors change their resistance as they are flexed.  When the monkey's arms move up and down, the values of the flex sensors change the number of LEDs that are turned on.
Changed lines 108-109 from:
Here's an example circuit much like the pink monkey circuit above, but with force-sensing resistors instead of flex sensors.
to:
Here's an example circuit much like the pink monkey circuit above, but with a force-sensing resistor instead of a flex sensor.
Changed lines 118-121 from:
The code above assumed you were using a potentiometer, which always gives the full range of analog input, which is 0 to 1023.  Dividing by 4 gives you a range of 0 to 255, which is the full output range of the @@analogWrite()@@ command. The voltage divider circuit, on the other hand, can't give you the full range. The fixed resistor in the circuit limits the range.  You'll need to modify the code. 

To find out your range, open
the serial monitor and watch the printout as you press the FSR or flex the flex sensor.  Note the maximum value and the minimum value. Then you can map the range that the sensor actually gives as input to the range that the LED needs as output. For example, if your photocell gives a range from 400 to 900, you'd do this:
to:
The code above assumed you were using a potentiometer, which always gives the full range of analog input, which is 0 to 1023.  The voltage divider circuit, on the other hand, can't give you the full range. The fixed resistor in the circuit limits the range.  You'll need to find your maximum and minimum values to determine the range for turning on the LEDs.

To find out your
range, open the serial monitor and watch the printout as you press the FSR or flex the flex sensor.  Note the maximum value and the minimum value. Then you can use the range that the sensor actually gives as input to the range that the LED needs as output.

You know that the maximum input
range of any analog input is from 0 to 5 volts.  So if you wanted to know the voltage on an analog input pin at any point, you use the map function to get it.
Deleted lines 124-133:
// map the sensor value from the input range (400 - 900, for example) to the output range (0-255):
int brightness = map(sensorValue, 400, 900, 0, 255);
analogWrite(ledPin, brightness);
(:sourceend:)

You know that the maximum input range of any analog input is from 0 to 5 volts.  So if you wanted to know the voltage on an analog input pin at any point, how could you use the map function to get it?

(:toggle questionVoltage init=hide show='I give up, how do I do that?' hide='Let me figure it out':)
>>id=questionVoltage border='1px solid #999' padding=5px bgcolor=#e1e7f1<<
(:source lang=arduino tabwidth=4 :)
Changed lines 133-137 from:
>><<


Now write a sketch to control the red LED with the first sensor (we'll call it the right hand sensor) and the green LED with the second sensor (we'll call it the left hand sensor). First, make two constants for the LED pin numbers, and two variables for the left and right sensor values.
to:


Now write a sketch to control the LEDs with the sensor so that as the sensor lets more voltage through, the number of LEDs that light up changes. First, make constants for the LED pin numbers, and a variable for the sensor values.
Changed lines 140-143 from:
const int redLED = 10;    // pin that the red LED is on
const int greenLED = 11;  // pin that the green LED is on
int rightSensorValue = 0// value read from the right analog sensor
int leftSensorValue = 0;  // value read from the left
analog sensor
to:
const int LEDone = 9;    // pin that the first LED is on
const int LEDtwo = 10;  // pin that the second LED is on
const int LEDone = 11  // pin that the third LED is on
const int LEDtwo = 12;  // pin that the fourth LED is on
const int sensorPin=0;  //pin that the sensor is on
int sensorValue = 0;  // value read from the
analog sensor
Changed lines 158-159 from:
  pinMode(redLED, OUTPUT);
  pinMode(greenLED, OUTPUT);
to:
  pinMode(LEDone, OUTPUT);
  pinMode(LEDtwo, OUTPUT);
  pinMode(LEDthree, OUTPUT);
  pinMode(LEDfour
, OUTPUT);
Changed lines 166-167 from:
Start the main loop by reading the right sensor using analogRead().  Map its range to a range from 0 to 255. Then use analogWrite() to set the brightness of the LED from the mapped value. Print the sensor value out as well.
to:
Start the main loop by reading the sensor using analogRead().  Print the sensor value out as well.
Changed lines 172-180 from:
  rightSensorValue = analogRead(A0); // read the pot value

  // map the sensor value from the input range (400 - 900, for example)
  // to the output range (0-255). Change the values 400 and 900 below
  // to match the range your analog input gives:
  int brightness = map(rightSensorValue, 400, 900, 0, 255);

  analogWrite(redLED, brightness);  // set the LED brightness with the result
  Serial.println(rightSensorValue
);  // print the sensor value back to the serial monitor
to:
  sensorValue = analogRead(sensorPin); // read the pot value

  Serial.println(sensorValue);  // print the sensor value back to the serial monitor
Changed lines 178-179 from:
Finish the main loop by doing the same thing with the left sensor and the green LED.
to:
Finish the main loop by setting up an if/else loop that turns the appropriate LEDs on/off.
Changed lines 183-191 from:
  // now do the same for the other sensor and LED:
  leftSensorValue = analogRead
(A1); // read the pot value

  // map the sensor value to the brightness again. No need to
  // declare the variable again
, since you did so above:
  brightness = map(leftSensorValue, 400, 900, 0, 255
); 

  analogWrite(greenLED, brightness);  // set the LED brightness with the result
  Serial.println(leftSensorValue);  // print the sensor value back to the serial monitor
to:
 
//assuming the values are between 400 and 900

if(sensorValue<450){
digitalWrite(LEDone, HIGH);
digitalWrite(LEDtwo, LOW);
digitalWrite(LEDthree, LOW);
digitalWrite(LEDfour, LOW);

}else if
(sensorValue >=450 && sensorValue<= 650){
digitalWrite(LEDone, HIGH);
digitalWrite(LEDtwo, HIGH);
digitalWrite(LEDthree, LOW);
digitalWrite(LEDfour, LOW);
}else if (sensorValue >=651 && sensorValue<= 775){
digitalWrite(LEDone, HIGH);
digitalWrite(LEDtwo, HIGH);
digitalWrite(LEDthree, HIGH);
digitalWrite(LEDfour, LOW);
}else if (sensorValue >=776){
digitalWrite(LEDone, HIGH);
digitalWrite(LEDtwo, HIGH);
digitalWrite(LEDthree, HIGH);
digitalWrite(LEDfour
, HIGH);
Added line 208:
}
Deleted lines 209-216:
>><<

!!! Get creative


''This is a suggestion for the Stupid Pet Trick assignment.  You can do any project you wish as long as it demonstrates your mastery of the lab exercises and good physical interaction. This is just one suggestion.''

Make a luv-o-meter with analog inputs.  A luv-o-meter is a device that measures a person's potential to be a lover, and displays it on a graph of lights.  In gaming arcades, the luv-o-meter is usually a handle that a person grips, and his or her grip is measured either for its strength or its sweatiness. But your luv-o-meter can measure any analog physical quantity that you want, providing you have a sensor for it. Make sure the display is clear, so the participant knows what it means, and make sure it is responsive.
February 15, 2012, at 12:13 PM by shf220 - Page Creation
Added lines 1-210:
(:title Analog In with an Arduino:)

!!!Overview

In this lab, you'll learn how to connect a variable resistor to a microcontroller and read it as an analog input.  You'll be able to read changing conditions from the physical world and convert them to changing variables in a program.

(:toc Table of Contents:)

!!! Parts

For this lab you will need to have the following parts:

%lframe width=100px% [[Attach:breadboard.jpg | Attach:breadboard.jpg"Solderless breadboard"]] | [-Solderless breadboard-]
%lframe width=100px% [[Attach:hookup_wire.jpg | Attach:hookup_wire.jpg"hookup wire"]] | [-22-AWG hookup wire-]
%lframe width=100px% [[Attach:arduino.jpg | Attach:arduino.jpg"Arduino module"]] | [-Arduino Microcontroller \\
module-]
[[<<]]
%lframe width=100px valign=center% [[Attach:leds.jpg | Attach:leds.jpg"Light Emiting Diodes"]] | [-Light Emiting Diodes, LED -]
%lframe width=100px valign=center% [[Attach:resistors_220.jpg | Attach:resistors_220.jpg"resistors"]] | [-560-ohm (anything from 220 to 1K) and 10Kohm resistors-]
%lframe width=90px valign=center% [[Attach:potentiometer.jpg | Attach:potentiometer.jpg"potentiometer"]] | [-10Kohm potentiometer-]
Variable resistors
%lframe width=90px valign=center% [[Attach:flex_sensors.jpg | Attach:flex_sensors.jpg"potentiometer"]] | [-Flex sensors\\
(or a different\\
 form of variable resistor)-]
[[<<]]

!!! Prepare the breadboard
Conect power and ground on the breadboard to power and ground from the microcontroller. On the Arduino module, use the 5V and any of the ground connections:

%lframe height=300 alt='Arduino connected to a breadboard' align=top valign=center%[[Attach:arduino_and_breadboard_bb.png|Attach:arduino_and_breadboard_bb.png]]
[[<<]]
[--(Diagram made with [[http://fritzing.org | Fritzing]])--]


!!! Add a potentiometer and LED

Connect a potentiometer to analog in pin 0 of the module, and an LED to digital pin 9:

%lframe alt='Arduino with potentiometer and LED' hspace=10 height=300%[[Attach:analog_in_lab_pot_and_led_bb.png|Attach:analog_in_lab_pot_and_led_bb.png]]
%lframe alt='Arduino with potentiometer and LED schematic' hspace=10 height=300%[[Attach:arduino_analog_input_schem.png|Attach:arduino_analog_input_schem.png]]
[[<<]]
[--(Diagram made with [[http://fritzing.org | Fritzing]])--]

!!! Program the Module

Program your Arduino as follows:

First, establish some global variables: One to hold the value returned by the potentiometer, and another to hold the brightness value. Make a global constant to give the LED's pin number a name.

(:toggle question1 init=hide show='I give up, how do I do that?' hide='Let me figure it out':)
>>id=question1 border='1px solid #999' padding=5px bgcolor=#e1e7f1<<
(:source lang=arduino tabwidth=4 :)
const int ledPin = 9;      // pin that the LED is attached to
int analogValue = 0;        // value read from the pot
int brightness = 0;        // PWM pin that the LED is on.
(:sourceend:)
>><<

In the setup() method, initialize serial communications at 9600 bits per second, and set the LED's pin to be an output.

(:toggle question2 init=hide show='I give up, how do I do that?' hide='Let me figure it out':)
>>id=question2 border='1px solid #999' padding=5px bgcolor=#e1e7f1<<
(:source lang=arduino tabwidth=4 :)
void setup() {
    // initialize serial communications at 9600 bps:
    Serial.begin(9600);
    // declare the led pin as an output:
    pinMode(ledPin, OUTPUT);
}
(:sourceend:)
>><<

In the main loop, read the analog value using analogRead() and put the result into the variable that holds the analog value.  Then divide the analog value by 4 to get it into a range from 0 to 255.  Then use the analogWrite() command to face the LED.  Then print out the brightness value.

(:toggle question3 init=hide show='I give up, how do I do that?' hide='Let me figure it out':)
>>id=question3 border='1px solid #999' padding=5px bgcolor=#e1e7f1<<
(:source lang=arduino tabwidth=4 :)
void loop() {
    analogValue = analogRead(A0);      // read the pot value
    brightness = analogValue /4;      //divide by 4 to fit in a byte
    analogWrite(ledPin, brightness);  // PWM the LED with the brightness value
    Serial.println(brightness);        // print the brightness value back to the serial monitor
}
(:sourceend:)
>><<

When you run this code, the LED should dim up and down as you turn the pot, and the brightness value should show up in the serial monitor.

!!! Other variable resistors

You can use many different types of variable resistors for analog input.  For example, the pink monkey in the photo below has his arms wired with flex sensors. These sensors change their resistance as they are flexed.  When the monkey's arms move up and down, the values of the flex sensors change the brightness of two LEDs.  The same values could be used to control servo motors, change the frequency on a speaker, or move servo motors. 

%alt='Monski with analog sensors'% [[Attach:monski_analog.JPG|Attach:monski_analog.JPG]]

'''Note''': Flex sensors and force-sensing resistors melt easily, so unless you are very quick with a soldering iron, it's risky to solder directly to their leads. Here are three better solutions:

%lframe alt='Force sensing resistor with wire wrapping wire' hspace=10 width=200%[[Attach:fsr_wire_wrap.jpg|Attach:fsr_wire_wrap.jpg]] | use wire wrapping wire \\
and a wire wrapping tool
%lframe alt='Force sensing resistor with screw terminals' hspace=10 width=200%[[Attach:fsr_screw_terminals.jpg|Attach:fsr_screw_terminals.jpg]] | use screw terminals \\
(if you have a row of three, you can \\
attach the fixed resistor as well)
%lframe alt='Force sensing resistor with female headers' hspace=10 width=200%[[Attach:fsr_female_headers.jpg|Attach:fsr_female_headers.jpg]] | use female headers
[[<<]]
Thanks to adafruit, who have a good [[http://www.ladyada.net/learn/sensors/fsr.html|FSR tutorial as well]].

Here's an example circuit much like the pink monkey circuit above, but with force-sensing resistors instead of flex sensors.

%lframe alt='Arduino with variable resistors and LED' hspace=10 width=300%[[Attach:arduino_fsrs_bb.png|Attach:arduino_fsrs_bb.png]]
%lframe alt='Arduino with variable resistors and LED schematic' hspace=10 width=300%[[Attach:arduino_fsrs_schem.png|Attach:arduino_fsrs_schem.png]]
[[<<]]
[--(Diagram made with [[http://fritzing.org | Fritzing]])--]


The circuit above works for any variable resistor. It's called a '''voltage divider'''. There are two voltage dividers, one on analog in 0 and one on analog in 1. The fixed resistor in each circuit should have the same order of magnitude as the variable resistor's range.  For example, if you're using a flex sensor with a range of 50 - 100 kilohms, you might use a 47Kohm or a 100Kohm fixed resistor. If you're using a force sensing resistor that goes from inifinity ohms to 10 ohms, but most of its range is between 10Kohms and 10 ohms, you might use a 10Kohm fixed resistor.

The code above assumed you were using a potentiometer, which always gives the full range of analog input, which is 0 to 1023.  Dividing by 4 gives you a range of 0 to 255, which is the full output range of the @@analogWrite()@@ command. The voltage divider circuit, on the other hand, can't give you the full range. The fixed resistor in the circuit limits the range.  You'll need to modify the code. 

To find out your range, open the serial monitor and watch the printout as you press the FSR or flex the flex sensor.  Note the maximum value and the minimum value. Then you can map the range that the sensor actually gives as input to the range that the LED needs as output. For example, if your photocell gives a range from 400 to 900, you'd do this:

(:source lang=arduino tabwidth=4 :)
// map the sensor value from the input range (400 - 900, for example) to the output range (0-255):
int brightness = map(sensorValue, 400, 900, 0, 255);
analogWrite(ledPin, brightness);
(:sourceend:)

You know that the maximum input range of any analog input is from 0 to 5 volts.  So if you wanted to know the voltage on an analog input pin at any point, how could you use the map function to get it?

(:toggle questionVoltage init=hide show='I give up, how do I do that?' hide='Let me figure it out':)
>>id=questionVoltage border='1px solid #999' padding=5px bgcolor=#e1e7f1<<
(:source lang=arduino tabwidth=4 :)
// read the sensor:
int analogValue = analogRead(A0);
// map the result to a voltage range from 0 to 5 volts
// using a floating point decimal variable (called a float):
float voltage = map(analogValue, 0.0, 5.0);
// print it out:
Serial.println(voltage);
(:sourceend:)
>><<


Now write a sketch to control the red LED with the first sensor (we'll call it the right hand sensor) and the green LED with the second sensor (we'll call it the left hand sensor). First, make two constants for the LED pin numbers, and two variables for the left and right sensor values.

(:toggle question4 init=hide show='I give up, how do I do that?' hide='Let me figure it out':)
>>id=question4 border='1px solid #999' padding=5px bgcolor=#e1e7f1<<
(:source lang=arduino tabwidth=4 :)
const int redLED = 10;    // pin that the red LED is on
const int greenLED = 11;  // pin that the green LED is on
int rightSensorValue = 0;  // value read from the right analog sensor
int leftSensorValue = 0;  // value read from the left analog sensor
(:sourceend:)
>><<

In the setup(), initialize serial communication at 9600 bits per second, and make the LED pins outputs.

(:toggle question5 init=hide show='I give up, how do I do that?' hide='Let me figure it out':)
>>id=question5 border='1px solid #999' padding=5px bgcolor=#e1e7f1<<
(:source lang=arduino tabwidth=4 :)
void setup() {
  // initialize serial communications at 9600 bps:
  Serial.begin(9600);
  // declare the led pins as outputs:
  pinMode(redLED, OUTPUT);
  pinMode(greenLED, OUTPUT);
}
(:sourceend:)
>><<

Start the main loop by reading the right sensor using analogRead().  Map its range to a range from 0 to 255. Then use analogWrite() to set the brightness of the LED from the mapped value. Print the sensor value out as well.

(:toggle question6 init=hide show='I give up, how do I do that?' hide='Let me figure it out':)
>>id=question6 border='1px solid #999' padding=5px bgcolor=#e1e7f1<<
(:source lang=arduino tabwidth=4 :)
void loop() {
  rightSensorValue = analogRead(A0); // read the pot value

  // map the sensor value from the input range (400 - 900, for example)
  // to the output range (0-255). Change the values 400 and 900 below
  // to match the range your analog input gives:
  int brightness = map(rightSensorValue, 400, 900, 0, 255);

  analogWrite(redLED, brightness);  // set the LED brightness with the result
  Serial.println(rightSensorValue);  // print the sensor value back to the serial monitor
(:sourceend:)
>><<

Finish the main loop by doing the same thing with the left sensor and the green LED.

(:toggle question7 init=hide show='I give up, how do I do that?' hide='Let me figure it out':)
>>id=question7 border='1px solid #999' padding=5px bgcolor=#e1e7f1<<
(:source lang=arduino tabwidth=4 :)
  // now do the same for the other sensor and LED:
  leftSensorValue = analogRead(A1); // read the pot value

  // map the sensor value to the brightness again. No need to
  // declare the variable again, since you did so above:
  brightness = map(leftSensorValue, 400, 900, 0, 255);

  analogWrite(greenLED, brightness);  // set the LED brightness with the result
  Serial.println(leftSensorValue);  // print the sensor value back to the serial monitor
}
(:sourceend:)
>><<

!!! Get creative


''This is a suggestion for the Stupid Pet Trick assignment.  You can do any project you wish as long as it demonstrates your mastery of the lab exercises and good physical interaction. This is just one suggestion.''

Make a luv-o-meter with analog inputs.  A luv-o-meter is a device that measures a person's potential to be a lover, and displays it on a graph of lights.  In gaming arcades, the luv-o-meter is usually a handle that a person grips, and his or her grip is measured either for its strength or its sweatiness. But your luv-o-meter can measure any analog physical quantity that you want, providing you have a sensor for it. Make sure the display is clear, so the participant knows what it means, and make sure it is responsive.
  Edit | View | History | Print | Recent Changes | Search Page last modified on February 15, 2012, at 06:16 PM