NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Microcontroller Programming » Temp spi help

September 01, 2011
by missle3944
missle3944's Avatar

Hi guys I'm just fooling around with spi between my 2 mcus and I was able to get them to work fine through spi. Now I made a spi temp sensor but for some reason my slave only sends one byte to the master or something like that. My slave has the temp sensor and all of the ADC code on it. But for some reason I cant tell if the master is only reading one byte or the slave is only sending one byte.

September 01, 2011
by Ralphxyz
Ralphxyz's Avatar

Dan, you can hard code a message string for the slave to send.

That way you take the temp sensor out of the equation.

Ralph

September 01, 2011
by missle3944
missle3944's Avatar

Ralph, how would I do this. Would I use an array? Heres my code for the slave if anyone has a suggestion ,too.

//
// slave_SPI.c
//
#define F_CPU 14745600
#include <avr/io.h> 
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <stdbool.h>
#include <stdlib.h>
#include <ctype.h>
#include <inttypes.h>
#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.h"
#include "../libnerdkits/io_328p.h"
#include <stdio.h>
#include <math.h>>

#include "../libnerdkits/delay.h"
#include "../libnerdkits/uart.h"

// preprocessor macros for port/pin manulipulation
//
#define INPUT2(port,pin) DDR ## port &= ~_BV(pin) 
#define OUTPUT2(port,pin) DDR ## port |= _BV(pin) 
#define CLEAR2(port,pin) PORT ## port &= ~_BV(pin) 
#define SET2(port,pin) PORT ## port |= _BV(pin) 
#define TOGGLE2(port,pin) PORT ## port ^= _BV(pin) 
#define READ2(port,pin) ((PIN ## port & _BV(pin))?1:0)
//------------------------------------------------------------
#define INPUT(x) INPUT2(x) 
#define OUTPUT(x) OUTPUT2(x)
#define CLEAR(x) CLEAR2(x)
#define SET(x) SET2(x)
#define TOGGLE(x) TOGGLE2(x)
#define READ(x) READ2(x)
#define PULLUP_ON(x) INPUT2(x); SET2(x)
#define PULLUP_OFF(x) INPUT2(x); CLEAR2(x)

void adc_init() {
  // set analog to digital converter
  // for external reference (5v), single ended input ADC0
  ADMUX = 0;

  // set analog to digital converter
  // to be enabled, with a clock prescale of 1/128
  // so that the ADC clock runs at 115.2kHz.
  ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);

  // fire a conversion just to get the ADC warmed up
  ADCSRA |= (1<<ADSC);
}

uint16_t adc_read() {
  // read from ADC, waiting for conversion to finish
  // (assumes someone else asked for a conversion.)
  // wait for it to be cleared
  while(ADCSRA & (1<<ADSC)) {
    // do nothing... just hold your breath.
  }
  // bit is cleared, so we have a result.

  // read from the ADCL/ADCH registers, and combine the result
  // Note: ADCL must be read first (datasheet pp. 259)
  uint16_t result = ADCL;
  uint16_t temp = ADCH;
  result = result + (temp<<8);

  // set ADSC bit to get the *next* conversion started
  ADCSRA |= (1<<ADSC);

  return result;
}

double sampleToFahrenheit(uint16_t sample) {
  // conversion ratio in DEGREES/STEP:
  // (5000 mV / 1024 steps) * (1 degree / 10mV)
  //    ^^^^^^^^^^^      ^^^^^^^^^^
  //     from ADC         from LM34
  return sample * (5000.0 / 1024.0 / 10.0);  
}
// local functions
void spi_slave_init(void);
uint8_t spi_recv_char(uint8_t send);

// define ports, pins
//
#define DD_MISO         B,4
#define DD_MOSI         B,3
#define DD_SCK          B,5
#define DD_SS           B,2

// --------------------------------------------------------------------------------------------------------
int main() {

    // start up the Analog to Digital Converter
  adc_init();

  // start up the serial port
  uart_init();
  FILE uart_stream = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW);
  stdin = stdout = &uart_stream;

  // holder variables for temperature data
  uint16_t last_sample = 0;
  double this_temp;
  double temp_avg;
  uint8_t i;

    // initialize SPI
    spi_slave_init();

    uint8_t byte_received;
    uint8_t byte_to_send;
 DDRD |= (1<<PD7);
 DDRD |= (1<<PD6);
    // get a byte, increment it, and send back
    while(1){
    temp_avg = 0.0;
    for(i=0; i<100; i++) {
      last_sample = adc_read();
      this_temp = sampleToFahrenheit(last_sample);

      // add this contribution to the average
      temp_avg = temp_avg + this_temp/100.0;
    }
    if (byte_received == 2){
        byte_received = spi_recv_char(temp_avg);

        printf_P(PSTR("%.2f degrees F\r\n"), temp_avg);
    }

        }
}
// --------------------------------------------------------------------------------------------------------
//
void spi_slave_init(void){
    // setup slave SPI pins
    OUTPUT(DD_MISO);
    INPUT(DD_MOSI);
    INPUT(DD_SCK);
    INPUT(DD_SS);
    // enable SPI
    SPCR = _BV(SPE);
}

uint8_t spi_recv_char(uint8_t send){
    // character to send
    SPDR = send;
    // wait for received character
    while(!(SPSR & _BV(SPIF)));
    // return recieved character
    return(SPDR);
}

Post a Reply

Please log in to post a reply.

Did you know that you can connect to certain car computers via the OBD-II port with a microcontroller? Learn more...