Is it possible to hard code the AREF instead of using a pin? - atmega

Is it possible to hard code the reference value instead of using the pin 21 (AREF) on the ATMEGA168?

Since the majority of ADC principles rely on comparision of voltage, current or charge you always need a physical reference that cannot be bypassed by hardcoding. In this case a reference voltage is needed. On the ATmega 168 you can either use the external reference pin AREF, or the controllers power supply voltage AVcc, or a built-in 1.1 V voltage reference diode 'Vref`.
You can set the reference source by programming ADMUX (ADC multiplexer selection register) as stated in the ATmega48/88/168 data sheet page 261:
//using avrgcc:
//select internal 1.1 V ADC reference
ADMUX |= 0b11000000;

Related

How to measure voltage above Reference Volt using MSP430?

I am learning to use MSP430 FR5994 for microcontroller development.
I wish to measure an external voltage using the built in ADC, the external voltage is in the range of 2.2V to 3.3V. The reference voltage set for the board is 1.2V (I can't use AVCC as the reference).
May I ask how should I measure the value of this voltage?

How to wire an A/D converter to measure within a specific voltage band so as not to waste measurement resolution

I am trying to use a MCP3008 A/D converter (see https://ww1.microchip.com/downloads/en/DeviceDoc/21295d.pdf) with a RaspberryPi to digitize an audio signal generated by some legacy audio chip.
From what I understand I could just power the MCP3008 with 3v3 (VDD) to ease connection to the RaspberryPi (or I could use higer VDD up to 7V but then I'd have to use an additional levelshifter to interface with the Raspberry). The MCP3008's reference voltage for analog input signals cannot be higher than VDD+0.6V (e.g. 3.9V or 7.6V for the mentioned scenarios.).
According to the specs of the soundchip that I want to sample the relevant peak-to-peak voltage change is only 3V but the signal seems to ride at a 6V DC level. (I imagine that means that the signal moves within the 4.5V to 7.5V range.. is that assumption correct?)
I could obviously use some voltage divider to scale the input voltage to whatever maximum reference voltage the MCP3008 will tolerate. But I would always waste most of the measurement range 0 - 4.5V due to the fact that it is never used by the original audio signal.
Is there anything I can do to make sure that a respective A/D converter (it might be a different model than the one mentioned above) uses its measurement resolution to digitize
the signal specifically within the relevant voltage range? (i.e. with a 10-bit converter a 4.5V
signal should translate into 0 and a 7.5V signal into 0x3ff).
PS: I wonder if it might be a viable approach to use a Z-diode to cut off some part of the DC level and then measure the "overflow" portion of the voltage over a 10k resistor that I'd put after the Z-diode. Or are there any reasons why this might not work well for my application?
Use a high pass filter to remove the DC bias.
Given that you are working with audio you need to be careful not to remove audio data.

Built-in led glowing on code of led on arduino mega

I had written a code on atmel studio for blinking a led on pin 13. After uploading the code with xloader mega's builtin led was blinking.
I uploaded fade code on my mega and the builtin led was blinking instead of led. What should i do?
I am using arduino mega 2560.
int main(void)
{
DDRB=0b00000000;
while (1)
{
PORTB=0b10000000;
_delay_ms(1000);
PORTB=0b00000000;
}
}
What you should do? Read the manual.
Please refer to https://ww1.microchip.com/downloads/en/devicedoc/atmel-2549-8-bit-avr-microcontroller-atmega640-1280-1281-2560-2561_datasheet.pdf
Chapter 13.2.
The DDxn bit in the DDRx Register selects the direction of this pin.
If DDxn is written logic one, Pxn is configured as an output pin. If
DDxn is written logic zero, Pxn is configured as an input pin.
Working with registers doesn't make sense if you don't know what they do.
DDRB=0b00000000;
Gives you inputs only.
why would you use Arduino and try to program it without its conventional macros and functions?
If you are trying to blink an led or make it breath then use the Arduino IDE and its built-in functions analogWrite() to generate a pwm pulse for your led or any led on suitable pins which support analogwrite(). You shouldn't try to do any direct modifications on registers if you have no suitable knowledge, because your risk destroying your development kit and maybe burning some other stuff around. Please use your kit's schematics to spot the pins which support analogwrite() and then use the code in examples.
That way you will achieve your goal faster and without any issues.
TL/DR: you have to set 7th bit in DDRB to one.
In AVR ports are configured by bits in two registers: DDRx and PORTx.
When the corresponding bit in the DDRx register is set to one, the port is configured as output. And the corresponding bit in the PORTx register chooses which electrical level is output on the pin. If it is 0 then internal MOSFET shorts the pin to "ground" lane, and sinks current from external source. When the bit of the PORTx is one, then the pin is connected to "VCC", sourcing big amount of current enough to lit up a LED.
But if the pin is connected to something, what consumes too much of current, or the pin is shorted to GND or VCC (let's say you have a button connected and pressed), then output MOSFETS might be overloaded and damaged.
If the bit in DDRx is set to zero, then the pin is configured as input. If the corresponding bit in the PORTx is zero, then the pin has no internal connection to power lines, it is called "Hi-impedance" state, or Tri-state. It does not source or sink any current. So, if no external source of current is connected, then pin level is floating, influenced by electrical interference. Logical level is not detectable and can change occasionally. If you want to connect, for example, a button (between the pin and GND), then logical level will be defined only when button is pressed. When it is released, the logical level will be undefined.
But! If the bit in the PORTx is set to one, then internal MOSFET connects the pin thru a resistor (about 35 kOhm) to VCC line. This make the pin to source a little amount of current, setting its logical level to high. Therefore, if a button is connected, when it is released, then pin will have defined high level. This is called "pull-up resistor". When button is pressed, it will not short and damage the MCU, because current flowing thru the button is limited by the resistor, but the logical level will be defined low.
What if instead of button you have a LED connected to the pin? Very small amount of current will flow thru the LED, makes it barely glow.
Read more in the datasheet (chapter 13. I/O-Ports)

Interrupting with SoftwareSerial on Arduino

I'm using Bluetooth serial port profile to communicate with Arduino. The bluetooth module (HC-06) is connected to my digital pins 10 and 11 (RX, TX). The module is working properly, but I need an interrupt on data receive. I can't periodically check for incoming data as Arduino is working on a time-sensitive task (music-playing through a passive buzzer) and I need control signals to interrupt immediately on receive. I've looked through many documents including Arduino's own site, and they all explain how to establish regular communication using checking for serialPort.available() periodically. I've found one SO question Arduino Serial Interrupts but that's too complicated for my level. Any suggestions on reading realtime input through serial?
Note that the current version of SoftSerial actually uses PCINT to detect the individual bits. Hence I believe defining it again at the main loop would conflict with the SoftSerial's actual detection of bits.
I am reluctant to suggest this as it is modifying a core library. Which is difficult not to do when sharing interrupts. But if desperate, you could modify that routine, with your need.
within
\arduino-1.5.7\hardware\arduino\avr\libraries\SoftwareSerial\SoftwareSerial.cpp.
//
// The receive routine called by the interrupt handler
//
void SoftwareSerial::recv()
{
...
// if buffer full, set the overflow flag and return
if ((_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF != _receive_buffer_head)
{
// save new data in buffer: tail points to where byte goes
_receive_buffer[_receive_buffer_tail] = d; // save new byte
_receive_buffer_tail = (_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF;
#ifdef YOUR_THING_ENABLE
// Quickly check if it is what you want and DO YOUR THING HERE!
#endif
}
...
}
But beware your are still in a ISR and all Interrupts are OFF and you are blocking EVERYTHING. One should not lollygag nor dilly dally, here. Do you something quick and get out.

Multitasking in PIC24

I have a PIC24 based system equipped with a 24 bit, 8 channels ADC (google MCP3914 Evaluation Board for more details...).
I have got the board to sample all of the 8 channels, store the data in a 512x8 buffer and transmit the data to PC using a USB module when the buffer is full (it's is done by different interrupts).
The only problem is that when the MCU is transmitting data (UART transmission interrupt has higher priority than the ADC reading interrupt) the ADC is not sampling data hence there will be data loss (sample rate is around 500 samples/sec).
Is there any way to prevent this data loss? maybe some multitasking?
Simply transmit the information to the UART register without using interrupts but by polling the bit TXIF
while (PIR1.TXIF == 0);
TXREG = "the data you want to send";
The same applies to the ADC conversion : if you were using interruptions to start / stop a conversion, simply poll the required bits (ADON) and thats it.
The TX bits and AD bits may vary depending on your PIC.
That prevents the MCU to enter an interrupt service routine and loose 3-4 samples.
In PIC24 an interrupt can be assigned one of the 8 priorities. Take a look at the corresponding section in the "Family Reference Manual" -> http://ww1.microchip.com/downloads/en/DeviceDoc/70000600d.pdf
Alternatively you can use DMA channels which are very handy. You can configure your ADC to use the DMA, and thus sampling and feeding the buffer won't use any CPU Time, same goes for UART I beleive.
http://ww1.microchip.com/downloads/en/DeviceDoc/39742A.pdf
http://esca.atomki.hu/PIC24/code_examples/docs/manuallyCreated/Appendix_H_ADC_with_DMA.pdf

Resources