[ Log In ]

Introduction to the Atmel Atmega32 AVR microcontroller and the pin assignments (what each pin of the chip does). The pins include PORTs (PORTA, PORTB, PORTC and PORTD) and 8 pins for each port, ADC (Analog to Digital Converter), PWM (Pulse Width Modulation), and serial forms of communicatgion like I2C, SPI, UART, USART, and much more.

An interrupt is an event that stops regular program flow to run a separate set of code that relates to the interrupt. Interrupts have many uses and applications. Interrupts can be used with:
- Timers and counters (When a timer matches a specific value)
- Serial communications (USART, UART - tell you when data is received, or when the transmit is ready to take data to transmit)
- When a pin goes from high to low or vice verse
- ADC (Analog to Digital Converter) completes the conversion
- Software interrupt (custom)
- And many others.

ADCor Analog to Digital Conversion is the way the microcontroller provides you with a digital number corresponding to the analog voltage you give the microcontroller.

The microcontroller has ADC pins that will accept a voltage between a reference voltage and 0 volts. A voltage from a device can be connected to this pin. When the pin reads the voltage, it will put a number corresponding to this voltage in a register.

The number the microcontroller gives you is in proportion to the amount of voltage. Say your reference voltage in your circuit is 5v and you put 2.5 volts to an ADC pin. The microcontroller would give you 128 in the ADC register if the 8-bit ADC is used, or would give you 512 if the 10-bit ADC is used. If the pin received the reference voltage of 5v, then the microcontroller would give you 255 for the 8-bit ADC and 1023 for the 10-bit ADC.

ADCVAlue = ReferenceVoltage / 10-bit Max Number or 8-Bit Max number

The 10-bit maximum is 1023 and 8-bit maximum is 255

A potentiometer is connected to the ADC using voltage divider connection to vary the voltage to the ADC pin. The output of the voltage to digital number is displayed on the LCD.

The center lead (Vout) of the potentiometer is connected to the ADC pin 0. The potentiometer's outer leads are connected to ground (GND) and 5V (VCC). These connections create the voltage divider. Optionally you can used resistors rather than wires for the two outer lead connections to minimize the possibility of a short where the resistance goes very low across the center lead to one of the outer leads.

The ADC needs to be powered. The ADC has its own power pins for AVCC and GND. the AVCC is connected directly to VCC (the 5V rail) and the GND is simply connected to GND on the - rail. Across these two power pins should reside a 100nf (nanofarad) or .1uf (microfarad) capacitor just like on the main power pins.

Another important pin for ADC is the voltage reference pin. This pin will receive the top voltage in our range of voltages we need to consider in the ADC input. Say, for instance, you don't want the 5v to be your voltage reference, because your device only has a range of 0v to 3.3v that will be delivered to the ADC. The top voltage in this range, 3.3v, should be connected to the ADC voltage reference Vref pin. If you had 5v connected to this Vref pin, but the device only gave you 0v to 3.3v, then your precision will be reduced.

The Vref pin can be set in programming, which is the case in this video clip.

The ADC (Analog to Digital Converter) converts an analog voltage between a range of voltages and provides an 8 to 10 bit number in proportion to the voltage sensed by the ADC.

In this video, the ADC automatically notifies of it's conversion complete using an interrupt. A potentiometer is used as a voltage divider to provide variable voltages to the ADC pin.

Enabling the ADC feature: ADEN - ADC Enable must be set in the ADCSRA register for the AVR Microcontroller

This is a general explanation of how the ADC pins and receiving analog voltages differ from the standard way of using the PORT pins.

When using the ADC, a prescaler must be established to have the ADC timer fall within an acceptable range. This input clock frequency acceptable range is between 50kHz and 200kHz.

To determine the prescaler value for these frequency ranges, take your clock frequency, usually defaulting at 1,000,000 for an Atmega32 and dividing that with the 50kHz and 200kHz to find the high and low prescaler values. With these values, just go to the table and determine the prescaler that falls between these results. (i.e. 1,000,000/50,000 = 20 and 1,000,000 / 200,000 = 5, so a prescaler between 5 and 20 is acceptable which is either 8 or 16).

Configuring the prescaler entails setting the ADPS2, ADPS1, and/or ADPS0 in the ADCSRA control and status register.

In the case of using a 16 prescaler, ADPS2 is the bit to be set.

Setting either a left shift or right shift for the result will make it easier to grab the data for 8-bit or 10-bit. It is how the number will be placed within the register that will hold the data. The number will be placed in the register as left justified or right justified using terminology from word processors. This is important because the data will reside in two registers, because a 10-bit number will not fit in just one 8-bit register.

The bit that needs to be set is ADLAR if you want the data to be shifted to the left. This will put the 8-bit information in one register called the ADCH (ADC High) and make it very easy to get the number without having to do any bitwise manipulations.

The ADLAR is in the ADMUX register.

Setting the interrupt control bit is located in the ADCSRA Control and Status Register. The bit to set in this register is ADIE (Analog to Digital Interrupt Enable).

Optionally, we can check the ADIF flag to manually determine if the ADC has completed a conversion.

Remember that the global interrupt must be set sei(); and the interrupt service routine and vector is established and another conversion is started within this service routine.

To use the interrupt for the ADC, an ISR (Interrupt Service Routine) must be established. This is just a function that resides outside of the main function that will run whenever the ADC completes a conversion. Once completed and the function is started, make sure the have code in that function that starts a new conversion. The ISR requires a parameter of the ISR vector. The vector for the ADC is ADC_vect.

The result from an ADC conversion is located in the ADCH register. Make sure to enable left shift to get all of the 8-bit data in the ADCH register. The ADLAR bit in the ADMUX register controls the left and right shift for the ADCH and ADCL registers.

The reference voltage for the ADC is the top threshold voltage that it will consider when making a conversion. That is to say, if the range of voltages on the ADC pin will be between 0 and 3.3 volts, then the reference voltage must be 3.3 volts rather than the voltage of the circuit.

In this case, the AVCC pin will provide us the reference voltage since the top threshold voltage will match the circuit's voltage.

The REFS1 and REFS0 bits in the ADMUX register will control where the reference voltage will be derived. If the REFS0 bit is set, then the AVCC will provide this reference.

The ADC allows the data registers (ADCH and ADCL) to be right adjusted or left adjusted. This makes it easier to pull the number out of the data registers (ADCH and ADCL). When left adjusted, its easy to get the 8-bit number from the ADCH since the full 8-bit number is stored in that register.

Right adjusted ADCH and ADCL is best for getting the data out of the ADCH and ADCL.

When a 10-bit number is desired from the ADC conversion, both the ADCH and ADCL must be used to get the full 10-bit number. The ADC stores the conversion in the ADCH and ADCL registers.

First, the ADCL register must be accessed and saved into another variable. The is a rule that must be followed when trying to get the 10-bit number.

Second, a variable will be needed to store the 10-bit conversion. A 16-bit variable is used. A bitwise shift operation will be used to get the data into the variable correctly. Both left adjusted (ADLAR = 1) and right adjusted (ADLAR = 0) will be shown.

When a 10-bit number is desired from the ADC conversion, both the ADCH and ADCL must be used to get the full 10-bit number. The ADC stores the conversion in the ADCH and ADCL registers.

First, the ADCL register must be accessed and saved into another variable. The is a rule that must be followed when trying to get the 10-bit number.

Second, a variable will be needed to store the 10-bit conversion. A 16-bit variable is used. A bitwise shift operation will be used to get the data into the variable correctly. The Right Adjusted method ADLAR = 0 is shown in this case.

The LCD is showing the 10-bit result from the ADC, getting the 10-bit conversion from the ADCH and ADCL registers and using the Left Adjusted ADLAR = 1.

When a 10-bit number is desired from the ADC conversion, both the ADCH and ADCL must be used to get the full 10-bit number. The ADC stores the conversion in the ADCH and ADCL registers.

First, the ADCL register must be accessed and saved into another variable. The is a rule that must be followed when trying to get the 10-bit number.

Second, a variable will be needed to store the 10-bit conversion. A 16-bit variable is used. A bitwise shift operation will be used to get the data into the variable correctly. The Right Adjusted method ADLAR = 0 is shown in this case.

Result of hte ADC 10-bit conversion shown on the LDC.

When a 10-bit number is desired from the ADC conversion, both the ADCH and ADCL must be used to get the full 10-bit number. The ADC stores the conversion in the ADCH and ADCL registers.

First, the ADCL register must be accessed and saved into another variable. The is a rule that must be followed when trying to get the 10-bit number.

Second, a variable will be needed to store the 10-bit conversion. A 16-bit variable is used. A bitwise shift operation will be used to get the data into the variable correctly. The Right Adjusted method ADLAR = 0 is shown in this case.

The ADC must run between 50kHz and 200kHz. This is an example of how to set the prescaler. The ADCSRA Control and Status Register is the register that contains the ADPS2, ADPS1 and ADPS0 bits that control the prescaler. In this case the 16 prescaler was selected since this microcontroller is running at 1mHz and 16 prescaler would allow the ADC to run between 50 and 200 kHz. The ADPS2 is the bit to set for this prescaler.

The AVR microcontroller offers an internal voltage reference of 2.56v to be used if so desired. If the device that is being measured by the ADC has a top value of 2.56v then this option would be a good one. The accelerometer that I am connecting to the ADC actually has a higher top voltage, but not that much more, so I selected this option.

The register that this option can be controlled is the ADMUX register. The REFS1 and REFS0 control the source of the reference voltage. In this case, to select the internal 2.56 volts as the reference, both REFS1 and REFS0 must be set.

To be able to use the interrupts with the ADC, the ADC Interrupt Enable (ADIE) must be set which is located in the ADCSRA Control and Status Register.

To enable the ADC, the ADEN bit must be set in the ADCSRA Control and Status Register.

To start a single ADC conversion, the ADSC (Analog to Digital Single Conversion) must be set in the ADCSRA Control and Status Register.

The ADLAR is not set in this program because it is 0 (right adjusted) by default.

When a 10-bit number is desired from the ADC conversion, both the ADCH and ADCL must be used to get the full 10-bit number. The ADC stores the conversion in the ADCH and ADCL registers.

First, the ADCL register must be accessed and saved into another variable. The is a rule that must be followed when trying to get the 10-bit number.

Second, a variable will be needed to store the 10-bit conversion. A 16-bit variable is used. A bitwise shift operation will be used to get the data into the variable correctly.

The ADLAR is not set in this program because it is 0 (right adjusted) by default.

When a 10-bit number is desired from the ADC conversion, both the ADCH and ADCL must be used to get the full 10-bit number. The ADC stores the conversion in the ADCH and ADCL registers.

First, the ADCL register must be accessed and saved into another variable. The is a rule that must be followed when trying to get the 10-bit number.

Second, a variable will be needed to store the 10-bit conversion. A 16-bit variable is used. A bitwise shift operation will be used to get the data into the variable correctly.

Capacitors can be used to smooth a rough or noisy signal. In this case, an accelerometer is being read by the ADC. The ADC is seeing a very noisy signal from the accelerometer.
A 10 uf (micro farad) capacitor is used to smooth the signal coming into the ADC. The result is a smoother signal and the response is acceptable, no apparent lag.

A 100 uf capacitor is also tested to determine if the signal can be smoothed even more. The result from the 100 uf capacitor is a bit smoother, but not enough to justify the use of a larger capacitor. The lag is greater with this capacitor and would probably be unacceptable.

Much of the noise may be coming from the breadboard itself, or the internal clock and other functions of the microcontroller.

The result from the ADC using the internal 2.56v reference and the accelerometer set at 1.5g is 325 at completely vertical and rotated 180 degrees the result is 963. This makes sense since we are not seeing the .5g's on either end of the rotation since we are only getting 1g, or the measure of gravity.

When doing conversions with the ADC (Analog to Digital Conversion), the result may have a variance from conversion to conversion. This gives you a method to calculate this deflection over time and some possible techniques to minimize this deflection, such as using capacitors or using the ADC sleep mode.

When doing conversions with the ADC (Analog to Digital Conversion), the result may have a variance from conversion to conversion. This gives you a method to calculate this deflection over time and some possible techniques to minimize this deflection, such as using capacitors or using the ADC sleep mode.

To be able to measure the previous result to the current result, the previous result must be stored. Once the current result is captured, another variable is incremented by the absolute value of the difference of the result and the previous result.

First a few global variables are needed to store the previous result, total deflection over time, and the sample count (they start static volatile because the compiler would optimize them out if these keywords were not there):

When doing conversions with the ADC (Analog to Digital Conversion), the result may have a variance from conversion to conversion. This gives you a method to calculate this deflection over time and some possible techniques to minimize this deflection, such as using capacitors or using the ADC sleep mode.
Using the LCD, the ADC values are shown for testing the ADC conversion and collecting the deflection over many samples.

To be able to measure the previous result to the current result, the previous result must be stored. Once the current result is captured, another variable is incremented by the absolute value of the difference of the result and the previous result.

First a few global variables are needed to store the previous result, total deflection over time, and the sample count (they start static volatile because the compiler would optimize them out if these keywords were not there):

The ACD result and deflection is tested with a capacitors: 10 uf (micro farad) and 100 uf.

The ADC has a noise cancelling features described below:

Circuit Specific: Analog Noise Cancelling Techniques: The ground plane specifications, using an inductor or 10 mH and 100 nf (nano farad) .1 uf (micro farad) capacitor.

Programming: ADC Noise Canceler - ADC noise reduction and idle mode. Entering the ADC noise reduction mode will cause the CPU to stop when the ADC is starting a conversion. This will only work in ADC single conversion mode.

the ADC noise reduction mode is invoked by setting the SM0 bit in the MCUCR register, make sure the SM1 and SM2 is not set. The SE (Sleep Enable) bit must also be enabled in the same register.

To convert more than one analog signal using the ADC, multiple channels must be used. In this case, an accelerometer will be connected to channel 0 and channel 1 of the ADC. The X axis is connected to channel 0 and the Y axis is connected to channel 1.

To smooth the analog signals, 10 uf (micro farad) capacitors will be used on each channel.

To power the accelerometer, the MAX604 voltage regulator with supporting capacitors are used.

This is a boilerplate code to initialize the ADC for interrupts and including the LCD library so the result can be displayed.

To select a channel of the ADC to use for input, the ADMUX must be set according to the channel that is used. The last 5 digits of the ADMUX register is used to select this channel.

To get ADC results on multiple pins of the ADC, we change the ADMUX to the channel that we want to receive the result, but this change needs to be done one at a time. That is to say, first we get invoke a conversion on channel 0 and get the result, then the channel is changed to 1 and we invoke a conversion and get the result. This is done for as many times as there are channels to collect data.

To get ADC results on multiple pins of the ADC, we change the ADMUX to the channel that we want to receive the result, but this change needs to be done one at a time. That is to say, first we get invoke a conversion on channel 0 and get the result, then the channel is changed to 1 and we invoke a conversion and get the result. This is done for as many times as there are channels to collect data.

This is a great vacuum pressure sensor that can sense up to about 40 inches of mercury (Hg) which is -115 KPa (Kilopascals). This range is perfect for many industrial uses for vacuum, including pick and place machines, vacuum forming, vacuum clamping for woodworking and gluing, and for vacuum hold down for CNC machines and the like.

The nozzle is located at the top which connects to a hose that is connected to the vacuum source.

The sensor has a die and a silicone diaphram that when moved from the pull of pressure will vary the internal resistance. Three of the 8 pins function, 2 for power VCC and GND and 1 pin to output an analog voltage of the relationship to the pressure sensed.

If used with a microcontroller, this pin would be connected to the ADC (Analog to Digital Converter) pin.

To have the microcontroller read a pressure sensor, the sensor is connected to the ADC (Analog to Digital Converter). In this case, the sensor is connected to the pin 0 of the ADC (PORT A).

AVCC (ADC Power VCC) is connected to the + rail and the AGND (ADC Ground) is connected to the - rail on the breadboard. Noise entering AVCC and AGND is filtered by a 100nf (nano farad) capacitor. The leads of the capacitor connect to the AVCC and AGND.

The pressure sensor is made into a breakout so it can be plugged into the bread board. The number 4 pin of the pressure sensor is connected to the pin 0 of the ADC. The number 2 pin of the pressure sensor is connected to the VCC 5v (since this is a 5v device) and the pin number 3 is connected to GND.

The LCD library and initialization is established. The interrupts for the ADC is started and a string is sent to the LCD. This is to get ready for the pressure sensor program. A string is sent to the LCD to create a label called Pressure.

The ADC clock must be between 50 KHz and 200 KHz to do the conversions. The ADC clock ticks with the microcontroller clock and a prescaler can be applied to the ADC clock so that the frequency is slower and in the range of 50 KHz and 200 KHz.

A prescaler of 16 will do the job for this microcontroller running at 1 MHzsince:

1,000,000 Hz / 16 = 62,500 Hz = 62.5 KHz.

The ADPS2 (ADC Pre Scaler) bit must be enabled in the ADCSRA (ADC Status and Control Register) to do this. There are three of these bits ADPS0 and ADPS1, but these are left at 0.

The reference voltage is the top voltage that will be considered in the conversion. The pressure sensor output will be between 0v and 5v. Our circuit already has this voltage handy and it exists at the AVCC pin, so that is used as the reference.

The REFS0 bit is set to enable the AVCC to be used as the reference voltage. This bit is located in the ADMUX register.

In the datasheet, if this option is used, a capacitor is required between the AREF pin to GND.

Enabling the ADC (turning the ADC on) is setting the ADEN (ADC Enable) in the ADCSRA (ADC Control and Status Register).

Starting a new single conversion is also in the ADCSRA and is the ADSC (ADC Single Conversion) bit.

to get the 10-bit number from the ADC conversion, the ADCL (ADC Low Data Byte) is read first (must be read first) and stored into another variable. The remaining data is located in the ADCH (ADC High Data Byte) and is moved 8 positions to the left so there is room for the ADCL variable byte. That result is stored in another variable and is sent to the LCD.

When the pressure sensor is tested to see the raw ADC 10-bit data on the LCD, the actual data did not appear. In the program, the bitwise operation for shifting and setting the ADEN (ADC Enable) to 1 was not correct. The shift operator uses two less than symbols and the program only had one less than symbol. It was a runtime error rather than an error at compile time is because the singe less than symbol is a valid symbol and valid in the context.

The LCD shows the results of a raw output from the ADC reading the pressure sensor. A simple test of the pressure sensor was made successfully.

In this case, the ADC result will be converted to Inches of Mercury (Hg). The pressure sensor provides us with a voltage between .2v and 4.6v. Since this is not the 0v to 5v which represents 0-1023 as ADC output, the actual result will need to be known.

The formula that converts the ADC value to inches of Hg (using the slope intercept formula):

inches of HG = -0.0377(ADC_Value) + 35.5134

The result of converting the ADC to a useful value of inches of Hg is displayed on the LCD.

The formula that converts the ADC value to inches of Hg (using the slope intercept formula):

inches of HG = -0.0377(ADC_Value) + 35.5134

An LED is connected to PORD Pin 0 of an AVR microcontroller. In this case, the LED is used to represent a motor that will turn on and off according to an ADC value.

The LED is connected to pin 0 on PORTD which is controlled by values from the ADC. The LED is actually representing a vacuum pump, so when the pressure sensor that is connected to the ADC passes a high threshold that will turn off the motor (pin to low) and if the ADC passes a low threshold, the motor will turn on (pin high). This will keep a vacuum in the tank between these two thresholds.

The LED is connected to pin 0 on PORTD which is controlled by values from the ADC. The LED is actually representing a vacuum pump, so when the pressure sensor that is connected to the ADC passes a high threshold that will turn off the motor (pin to low) and if the ADC passes a low threshold, the motor will turn on (pin high). This will keep a vacuum in the tank between these two thresholds.

Trimmer Potentiometers are small potentiometers intended only to be adjusted on the circuit and these are generally not able to be accessed. For example, a radio has a volume control that my be a standard potentiometer, but if you break open the case and pull out the circuit board, there may be small potentiometers (trimmers) on the board that cam be adjusted with a screwdriver.

The two trimmers are connected to the ADC pins 1 and 2 to adjust a low and high threshold.

Two trimmers are connected to the ADC one on channel 1 and the other on channel 2. The pressure sensor is connected to channel 0.

The two trimmers will be adjusting a low threshold and a high threshold for the pressure sensor and pin output function.

The trimmer potentiometers are used to adjust the high and low thresholds for the pressure sensor circuit. The adjustment needs to read between 0 and 33 rather than the ADC result of 0 and 1023, so the slope intercept formula is a good formula to use in this case.

The code in the ADC channels are updated to reflect the slope intercept formula so the trimmer potentiometers show a range or 0 - 33 rather than the raw ADC result of 0 - 1023.

The code in the ADC channels are updated to reflect the slope intercept formula so the trimmer potentiometers show a range or 0 - 33 rather than the raw ADC result of 0 - 1023.

A resistor will most likely be needed at the base lead of a transistor if the transistor will be used as a switch. The formla below is a special formula that is used only if the supply voltage is the same as the voltage being applied to the base lead of the transistor

Resistance = LoadCurrent x LoadResistance x Hfe(transistor rated)

Create an event dispatcher by clicking the main event dispatcher icon in the My Blueprint panel. Name the event dispatcher appropriately.

An event dispatcher creates an event for which other blueprints can listen. It's a way to broadcast to any other blueprint that something happened in this class blueprint.

Drag that event dispatcher into the event graph and click on call. Setup an event hit to determine if a mesh is hit by right clicking on the graph and typing event hit and selecting it. The event hit can be connected to the event dispatcher so all blueprints will know about it.

In the other blueprint (i.e. the level blueprint), with the

Thanks for the push button code and ADC examples Patrick. Your website motivated me to transition from Arduino and Intel Edison (in mraa) to the real deal.

Best wishes,
Jordan

Thanks for the push button code and ADC examples Patrick. Your website motivated me to transition from Arduino and Intel Edison (in mraa) to the real deal.

Best wishes,
Jordan