Go Down

Topic: SPI interface with other board_AVR_ESK1100 or among Arduino itself (Read 14066 times) previous topic - next topic

ranjeetray


OK, now re-read reply #4 and explain why you ignored his suggestion.


Respected Sir

Thanks a lot for your kind reply. I have tried with his suggestion also but still I was getting value 0. Please explain me in depth. I am doing something wrong which I am not able to understand. Kindly guide me.

I had used this code also
Code: [Select]

byte WriteByte (byte value) {
  SPDR = value ;
  while (!(SPSR & (1<<SPIF)))
  {}
  return SPDR ;
}

ranjeetray


I think your WriteByte routine is failing to complete the process - it reads SPSR but doesn't read SPDR once there's a byte so the hardware never clears ready for the next byte?  To quote the datasheet:
Quote
the SPIF bit is cleared by first reading the SPI Status Register with SPIF set, then accessing the SPI Data Register (SPDR)


  How about rewriting WriteByte thus:
Code: [Select]


byte WriteByte (byte value) {
  SPDR = value ;
  while (!(SPSR & (1<<SPIF)))
  {}
  return SPDR ;
}

(So easy to miss a semicolon after a while, use a blank block instead, harder to misread)


Respected Sir

I have used this code also but getting the same value as 0.
Please explain me how to make SPDR to work.


Code: [Select]

byte WriteByte (byte value) {
  SPDR = value ;
  while (!(SPSR & (1<<SPIF)))
  {}
  return SPDR ;
}

Nick Gammon

Code: [Select]

 byte ReadByte(void) {
 
 while(!(SPSR & (1<<SPIF)))
   return SPDR;
}



Do you see a similar problem here?

MarkT said:

Quote
(So easy to miss a semicolon after a while, use a blank block instead, harder to misread)
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

ranjeetray

#18
Aug 29, 2012, 09:40 am Last Edit: Aug 29, 2012, 09:55 am by ranjeetray Reason: 1

Code: [Select]

 byte ReadByte(void) {
 
 while(!(SPSR & (1<<SPIF)))
   return SPDR;
}



Do you see a similar problem here?

MarkT said:

Quote
(So easy to miss a semicolon after a while, use a blank block instead, harder to misread)



Respected Sir

When I use ; it goes in infinite loop and does not give any output and without ; it gives output as
Output:
Code: [Select]

Read value
0
Read value
0
Read value
0
Read value
0
Read value
0
Read value
0
Read value
0
Read value
0
Read value
0
Read value
0
Read value
0
Read value
0
Read value
0


Sir ,
Is this code correct, please suggest if something is wrong:
Code: [Select]

#include <SPI.h>// include the SPI library:

const int spidata = 10;//Pin 11 is data(MOSI) and pin 13 SCK ,set pin 10(SS) as the slave select for the digital pot:

void setup() {
 
 pinMode (spidata, INPUT);// set the spi_data_pin as an output:
 SPI.setDataMode(SPI_MODE3);
 SPI.setClockDivider(SPI_CLOCK_DIV8);
 SPI.begin();// initialize SPI:
 Serial.begin(9600);}
 
 byte ReadByte(void) {
 
 while(!(SPSR & (1<<SPIF)));
   return SPDR;
}

void loop() {
 
     int rxData;
 
   digitalWrite(spidata,LOW);
     rxData = ReadByte();
     Serial.println("Read value ");
    Serial.println(rxData, DEC);
   digitalWrite(spidata,HIGH);
  delay(1500);
}


Nick Gammon

Will you please explain why you are not using SPI.transfer() ?
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

MarkT

That's a good point - SPI.transfer will work for both master and slave I think (master mode doesn't require the SPDR to be read, but transfer does this anyway).
[ I won't respond to messages, use the forum please ]

Graynomad

There was an almost exact same problem on this thread

http://arduino.cc/forum/index.php/topic,118712.0.html

Same code even.

I still don't know why it didn't work but using SPI.transfer() fixed it.

______
Rob
Rob Gray aka the GRAYnomad www.robgray.com

ranjeetray


There was an almost exact same problem on this thread

http://arduino.cc/forum/index.php/topic,118712.0.html

Same code even.

I still don't know why it didn't work but using SPI.transfer() fixed it.

______
Rob


Dear Sir

Thanks a lot for your kind support.

Can you please provide us the both master and slave codes, it will be great help for me.

Thanks & Regards..

ranjeetray

#23
Aug 30, 2012, 07:15 am Last Edit: Aug 30, 2012, 07:21 am by ranjeetray Reason: 1

Will you please explain why you are not using SPI.transfer() ?


Respected Sir

Thanks a lot for your kind support. Now I am able to receive data form master but after receiving I want to send some data to master back, how can we do this. I have used SPI.transfer() in the master/data-sending code.
Working code.

Sending data code:
Code: [Select]

#include <SPI.h>// include the SPI library:

const int spidata = 10;//Pin 11 is data(MOSI) and pin 13 SCK ,set pin 10(SS) as the slave select for the digital pot:
int mm =0;

void setup() {
 
 pinMode (spidata, OUTPUT);// set the spi_data_pin as an output:
 
 SPI.begin();// initialize SPI:
 Serial.begin(9600);
}

void loop() {
   
     digitalWrite(spidata,LOW);
     SPI.transfer(0x3b); //  send in the address and value via SPI:
     digitalWrite(spidata,HIGH);// take the SS pin high to de-select the chip:
     delay(1500);
   }



Receiving data code:
Code: [Select]

#include <SPI.h>
#include <stdio.h>
#include <avr/io.h>
#include <stdlib.h>

#define MOSI 11
#define MISO  12
#define SCK  13
#define SS 10

int data = 0;
char buff[8];


void setup()
{
 pinMode(MOSI, INPUT);
 pinMode(MISO, OUTPUT);
 pinMode(SCK,INPUT);
 pinMode(SS,INPUT);

 Serial.begin(9600);
 SPCR = 0x40;  // Enable SPI in slave mode
//  SPI.begin();
 delay(500);
 
}

void loop()
{

 Serial.println("Data Received from Master Board");
 data = SPI_SlaveReceive();
  Serial.println(data, HEX);
 data = 0;

}

unsigned char SPI_SlaveReceive()
{
 while(!(SPSR & (1<<SPIF)));
 return SPDR;
}




Output from receiving code:
Code: [Select]

Data Received from Master Board
3B
Data Received from Master Board
3B
Data Received from Master Board
3B
Data Received from Master Board
3B




And now what should I do modification in the code so that I can send some data to master once I receive 0x3B from master.
I am trying like this at receiving(slave) side, it is receiving 0x3B from master but not able to send data to master
Code: [Select]

#include <SPI.h>
#include <stdio.h>
#include <avr/io.h>
#include <stdlib.h>

#define MOSI 11
#define MISO  12
#define SCK  13
#define SS 10
#define sss 9
int data = 0;
char buff[8];


void setup()
{
 pinMode(MOSI, INPUT);
 pinMode(MISO, OUTPUT);
 pinMode(SCK,INPUT);
 pinMode(SS,INPUT);
 pinMode(sss, OUTPUT);

 Serial.begin(9600);
 SPCR = 0x40;  // Enable SPI in slave mode
//  SPI.begin();
 delay(500);
 
}

void loop()
{
int xx;
 Serial.println("Data Received from Master Board");
 data = SPI_SlaveReceive();
 
 xx = data;
 
  Serial.println(data, HEX);
 data = 0;
 delay(20);
 if(xx == 59)
 {
   delay(600);
   void master_init();
   unsigned char send2();
   delay(600);
 }
}
 unsigned char send2(){
 digitalWrite(SS, LOW);
 WriteByte(16);
 digitalWrite(SS, HIGH);
 delay(600);}

unsigned char SPI_SlaveReceive()
{
 while(!(SPSR & (1<<SPIF)));
 return SPDR;
}
void master_init()
{
   pinMode(MOSI, OUTPUT);
 pinMode(MISO, INPUT);
 pinMode(SCK,OUTPUT);
 pinMode(SS,OUTPUT);
 pinMode(sss, OUTPUT);
 
}
void WriteByte(byte value) {
 SPDR = value;
 while (!(SPSR & (1<<SPIF))) ;
 return;
}

And at the master side I am doing like this but it is not able to receive the data
Code: [Select]


#include <SPI.h>// include the SPI library:

const int spidata = 10;//Pin 11 is data(MOSI) and pin 13 SCK ,set pin 10(SS) as the slave select for the digital pot:
#define sss 9
int mm =0;
unsigned char data1 = 0;

void setup() {
 
 pinMode (spidata, OUTPUT);// set the spi_data_pin as an output:
 
 SPI.begin();// initialize SPI:
 Serial.begin(9600);
}

void loop() {
    //for(mm=0; mm<23;mm++){
     digitalWrite(spidata,LOW);
     //Serial.println("I am writting on SPI");
     //Serial.println(mm, BIN);
     SPI.transfer(0x3b); //  send in the address and value via SPI:
    // SPI.transfer('IMU');
     
     digitalWrite(spidata,HIGH);// take the SS pin high to de-select the chip:
     delay(600);
     //digitalWrite(sss,LOW);
     
     
     unsigned char read1();
     delay(600);
     //digitalWrite(sss,HIGH);
     
    }
    unsigned char read1()
     {
       void slave_init();
     data1 = read_ready();
     
     Serial.println(data1, DEC);
     data1 = 0;
     
     delay(60);
     
     }
     
     
     unsigned char read_ready()
     {
       while(!(SPSR & (1<<SPIF)));
       return SPDR;
   
   }
  void slave_init()
  {
    SPCR = 0x40;
   pinMode(11, INPUT);
   pinMode(12, OUTPUT);
   pinMode(13, INPUT);
   pinMode(10, INPUT);
   delay(600);
   
  }

Kindly suggest me for the modification.

ranjeetray


That's a good point - SPI.transfer will work for both master and slave I think (master mode doesn't require the SPDR to be read, but transfer does this anyway).


Dear Sir

Thanks a lot for your kind support. Kindly go through the post  Reply #23 on: Today at 05:15:07 PM and please suggest for the modification on the code.


Thanks and Regards.

Nick Gammon

Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

ranjeetray



Kindly go through the post  Reply #23 ...


Kindly stop ignoring our suggestions.

Dear Sir

Where do you want me to use this SPI.transfer() function in my code, And I am not trying to avoid yours suggestion. Please guide me and help me out.


Thanks & Regards..

ranjeetray



Kindly go through the post  Reply #23 ...


Kindly stop ignoring our suggestions.


Respected Sir,

This code is able to send the data but not able to receive, what is wrong in this;

Code: [Select]



//send receive
#include <SPI.h>// include the SPI library:
#define SCK_PIN   13
#define MISO_PIN  12
#define MOSI_PIN  11
//#define SS_PIN    10
unsigned char receive_data(void);




const int spidata = 10;//Pin 11 is data(MOSI) and pin 13 SCK ,set pin 10(SS) as the slave select for the digital pot:

unsigned char rd = 0;

void SlaveInit(void) {
  // Set MISO output, all others input
  pinMode(SCK_PIN, INPUT);
  pinMode(MOSI_PIN, OUTPUT);
  pinMode(MISO_PIN, INPUT);
  pinMode(spidata, INPUT);
  Serial.begin(9600);

  // Enable SPI
  SPCR = B00101100;
     SPCR = (1<<SPE);
     //SPCR = 0x00;
   
}

void setup() {
 
   pinMode(SCK_PIN, OUTPUT);
  pinMode(MOSI_PIN, INPUT);
  pinMode(MISO_PIN, OUTPUT);
  pinMode(spidata, OUTPUT);
 
  //pinMode (spidata, OUTPUT);// set the spi_data_pin as an output:
 
  SPI.begin();// initialize SPI:
  Serial.begin(9600);
  //SPI.setBitOrder(LSBFIRST);
  //SPCR = 0x90;
}

void loop() {digitalWrite(spidata,LOW);
            SPI.transfer(0x3b); //  send in the address and value via SPI:
            digitalWrite(spidata,HIGH);
            delay(400);
           receive_data();
           
            }
   
   
    unsigned char read_data(void)
    {  //SPCR = 0x60;
      while(!(SPSR & (1<<SPIF)));
      return SPDR; }
   
    unsigned char receive_data(){
     
    pinMode(spidata, INPUT);
     SlaveInit();
     rd = read_data();
      Serial.println(rd, DEC);
      rd = 0;
      delay(400);
      return 0;
    }
     
     
     
     

ranjeetray


Quote
Even this code is working fine .

Then, what IS your problem?


Respected Sir,

Can we read/transmit here 16 bit data on Arduino board using SPI protocol. Will it generate 16 continuous clock signal.

Graynomad

The Arduino has an 8-bit SPI peripheral and therefore only transmits 8 bits at a time.

However you can just transmit two bytes in a row, the end result is the same.

______
Rob
Rob Gray aka the GRAYnomad www.robgray.com

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy