Temperature and Light Sensor using atxmega128a1

Go To Last Post
10 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I want to design a Temperature and Light Sensor using atxmega128a1 which can read at the intervals of 2 minutes and send the value via serial interface to the CPU and save it in a file.

It should also be able to sound an alarm when the temperature is below 20 degree and above 30 degree. However I am facing a lot of problems with the codes since I am a total beginner in this. I tried to combine the USART code with the temperature sensor code but this doesn't seem to work (Also it is very tough to test as the device connects like 1% of the time and I couldn't find a virtual software to test this without the actual device). It will be much appreciated if you could help me with the code.

/**
 * \file
 *
 * \brief AVR XMEGA Analog to Digital Converter Driver Example 1
 *
 * Copyright (c) 2010-2018 Microchip Technology Inc. and its subsidiaries.
 *
 * \asf_license_start
 *
 * \page License
 *
 * Subject to your compliance with these terms, you may use Microchip
 * software and any derivatives exclusively with Microchip products.
 * It is your responsibility to comply with third party license terms applicable
 * to your use of third party software (including open source software) that
 * may accompany Microchip software.
 *
 * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
 * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
 * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
 * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
 * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
 * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
 * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
 * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE.  TO THE FULLEST EXTENT
 * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
 * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
 * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
 *
 * \asf_license_stop
 *
 */

/**
 * \mainpage
 *
 * \section intro Introduction
 * This simple example shows how to use the \ref adc_group for temperature
 * measurement with the internal sensor.
 *
 * \section files Main files:
 * - adc_example1.c: ADC driver example application
 * - conf_adc.h: configuration of the ADC driver
 *
 * \section apiinfo ADC driver API
 * The ADC driver API can be found \ref adc_group "here".
 *
 * \section deviceinfo Device Info
 * All AVR XMEGA devices with an ADC can be used.
 *
 * \section exampledescription Description of the example
 * ADC A is configured for unsigned, 12-bit conversions using the internal 1 V
 * voltage reference. The conversions are configured for manual triggering.
 * Channel 0 of the ADC is configured for single-ended measurements from the
 * internal temperature sensor.
 *
 * An ADC interrupt callback function is used to handle the conversion results,
 * from which the current temperature, in kelvin, is computed. The computation
 * requires the factory calibration measurement, and is done according to the
 * following formula (T = temperature, R = ADC result):
 * \f[ T_\textnormal{now} = \frac{(R_\textnormal{now} \cdot
 * T_\textnormal{calibration})}{R_\textnormal{calibration}}
 * \f]
 *
 * The computed temperature is stored in the global variable
 * \ref last_temperature, which can, e.g., be watched during debugging.
 *
 * \section compinfo Compilation Info
 * This software was written for the GNU GCC and IAR for AVR.
 * Other compilers may or may not work.
 *
 * \section contactinfo Contact Information
 * For further information, visit
 * <A href="http://www.atmel.com/">Atmel</A>.\n
 */
/*
 * Support and FAQ: visit <a href="https://www.microchip.com/support/">Microchip Support</a>
 */
#include <asf.h>
#include <stdio.h>
#include <avr/io.h>

//! Temperature sensor calibration data.
static uint16_t tempsense;

//! The latest, computed temperature.
static volatile uint16_t last_temperature;

/**
 * \brief Callback function for ADC interrupts
 *
 * \param adc Pointer to ADC module.
 * \param ch_mask ADC channel mask.
 * \param result Conversion result from ADC channel.
 */
static void adc_handler(ADC_t *adc, uint8_t ch_mask, adc_result_t result)
{
	uint32_t temperature;

	/* Compute current temperature in kelvin, based on the factory
	 * calibration measurement of the temperature sensor. The calibration
	 * has been done at 85 degrees Celsius, which corresponds to 358 kelvin.
	 */
	temperature = (uint32_t)result * 358;
	temperature /= tempsense;

	// Store temperature in global variable.
	last_temperature = temperature & 0xffff;

	// Start next conversion.
	adc_start_conversion(adc, ch_mask);
}


static int uart_putchar(char c, FILE *stream);
static void uart_init (void);

static FILE mystdout = FDEV_SETUP_STREAM (uart_putchar, NULL, _FDEV_SETUP_WRITE);



static int uart_putchar (char c, FILE *stream)
{
	if (c == '\n')
	uart_putchar('\r', stream);

	// Wait for the transmit buffer to be empty
	while ( !( USARTC0.STATUS & USART_DREIF_bm) );
	
	// Put our character into the transmit buffer
	USARTC0.DATA = c;

	return 0;
}


// Init USART.  Transmit only (we're not receiving anything)
// We use USARTC0, transmit pin on PC3.
// Want 9600 baud. Have a 2 MHz clock. BSCALE = 0
// BSEL = ( 2000000 / (2^0 * 16*9600)) -1 = 12
// Fbaud = 2000000 / (2^0 * 16 * (12+1))  = 9615 bits/sec
static void uart_init (void)
{
	// Set the TxD pin high - set PORTC DIR register bit 3 to 1
	PORTC.OUTSET = PIN3_bm;
	
	// Set the TxD pin as an output - set PORTC OUT register bit 3 to 1
	PORTC.DIRSET = PIN3_bm;

	// Set baud rate & frame format
	USARTC0.BAUDCTRLB = 0;			// BSCALE = 0 as well
	USARTC0.BAUDCTRLA = 12;

	// Set mode of operation
	USARTC0.CTRLA = 0;				// no interrupts please
	USARTC0.CTRLC = 0x03;			// async, no parity, 8 bit data, 1 stop bit

	// Enable transmitter only
	USARTC0.CTRLB = USART_TXEN_bm;
}

int main(void)
{
	struct adc_config         adc_conf;
	struct adc_channel_config adcch_conf;

	board_init();
	sysclk_init();
	sleepmgr_init();
	irq_initialize_vectors();
	cpu_irq_enable();

	// Initialize configuration structures.
	adc_read_configuration(&ADCA, &adc_conf);
	adcch_read_configuration(&ADCA, ADC_CH0, &adcch_conf);

	/* Configure the ADC module:
	 * - unsigned, 12-bit results
	 * - bandgap (1 V) voltage reference
	 * - 200 kHz maximum clock rate
	 * - manual conversion triggering
	 * - temperature sensor enabled
	 * - callback function
	 */
	adc_set_conversion_parameters(&adc_conf, ADC_SIGN_OFF, ADC_RES_12,
			ADC_REF_BANDGAP);
	adc_set_clock_rate(&adc_conf, 200000UL);
	adc_set_conversion_trigger(&adc_conf, ADC_TRIG_MANUAL, 1, 0);
	adc_enable_internal_input(&adc_conf, ADC_INT_TEMPSENSE);

	adc_write_configuration(&ADCA, &adc_conf);
	adc_set_callback(&ADCA, &adc_handler);

	/* Configure ADC channel 0:
	 * - single-ended measurement from temperature sensor
	 * - interrupt flag set on completed conversion
	 * - interrupts disabled
	 */
	adcch_set_input(&adcch_conf, ADCCH_POS_TEMPSENSE, ADCCH_NEG_NONE,
			1);
	adcch_set_interrupt_mode(&adcch_conf, ADCCH_MODE_COMPLETE);
	adcch_enable_interrupt(&adcch_conf);

	adcch_write_configuration(&ADCA, ADC_CH0, &adcch_conf);

	// Get measurement for 85 degrees C (358 kelvin) from calibration data.
	tempsense = adc_get_calibration_data(ADC_CAL_TEMPSENSE);

	// Enable the ADC and start the first conversion.
	adc_enable(&ADCA);
	adc_start_conversion(&ADCA, ADC_CH0);
	
	do {
		// Sleep until ADC interrupt triggers.
		sleepmgr_enter_sleep();
	} while (1);
	
	uart_init();
	stdout = &mystdout;
	while (1)
	printf(tempsense);
}

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

atharv1998 wrote:
and I couldn't find a virtual software to test this without the actual device).

Pardon?  You mean a terminal program like Brays Terminal, or PuTTY for example?

 

Others may disagree with me on this, but if you haven't tried using Atmel START to configure your part I would recommend using that to confirm all operations of your peripherals since you are a beginner as you say. 

 

JIm

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No I meant like how there are so many virtual devices available for arduino so we can test our code without the actual device. Also there aren't so many examples of ATxmega128a1 available on Atmel START. The example code in atmel does not display the temperature so I am just trying to use USART to do that.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So many questions, I’m not sure where to start!
Why or how did you chose an XMEGA device over a simpler mega? School project? Prof said made it with XMEGA?
It sounds like you have jumped right in to coding without a plan first!
What temp sensor will you use? Analog? I2C?
You said serial interface, do you have a USB to TLL serial cable?
I just have to say, if you chose an Arduino solution this project would already be done as there must be a gillion temp sensor projects on the net to copy .

Jim

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes its for a school project that we are suppose to do with this micro controller only. We want to use the internal temperature and ambience sensor on board for this project.

We have tried to print Hello world using USART on data visualizer in Atmel Studio but we are facing issues in getting sensor data.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ki0bk wrote:
It sounds like you have jumped right in to coding without a plan first!

https://www.avrfreaks.net/commen...

 

atharv1998 wrote:
the internal ... ambience sensor

The what?

 

We have tried to print Hello world using USART on data visualizer in Atmel Studio

Did you succeed?

 

we are facing issues in getting sensor data

What do you mean by that?

  • reading it from the sensors?
  • sending it via the USART?
  • other?

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1
	while (1)
	printf(tempsense);

First just don't do that. Don't even do:

        while (1)
            printf(tempsense);

But do it as:

	while (1) {
	    printf(tempsense);
        }

But let's look at what's going on here. printf() is a variadic function. It takes one mandatory parameter which is a char* then, dependent on the content of that it takes 0 or more following parameters. But you have:

static uint16_t tempsense;

so you are calling printf() with just a uint16_t. Did you, perhaps, mean something like:

	    printf("%u\n",tempsense);

but if you have:

	while (1) {
	    printf("%u\n",tempsense);
        }

then isn't this going to simply print the same thing over and over again? The only way this might work would be if "tempsense" were being set to varying values somewhere else. The only "somewhere else" that could be would be in an interrupt but I don't see any code setup to do that and even if there were it still wouldn't work because in such circumstances tempsense would have to be "volatile".

 

Or maybe "tempsense" is not the actual temperature reading? But if that is the case why print it repeatedly in the while(1) ? Did you mean to print "last_temperature" there instead?

 

It does seem:

ki0bk wrote:
It sounds like you have jumped right in to coding without a plan first!

You should sketch out a picture in your mind (or even on paper) of the major steps of activity that this program needs to do and how it will achieve it - only start writing C code when you have that clear plan in your head.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
You should sketch out a picture in your mind (or even on paper)

I would say that having it on "paper" (physical or virtual) is an absolute necessity - not an option.

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't agree - it depends on the complexity of the system. If you are planning to write the code to flight an A380 then, yes, something written down makes sense. If you are designing a program to use an ADC to read a sensor and flash an LED when the reading exceeds a certain amount I think most normal humans could hold the complexity of that in their brain alone.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The main problem is that the example code of Light sensor in Atmel Studio of the board wont get uploaded on the board using FLIP. As soon as we select the file it will give an error that "Address is out of range" which is not because size of the file is too big as bigger codes are running fine. So I tried finding some alternative to FLIP but couldn't find one that supports this specific microcontroller. Can someone help with this issue? At least the example code should run fine!

Last Edited: Sat. Sep 14, 2019 - 07:07 AM