Go Down

Topic: Reading data from Flow sensor with EEPROM (Read 3131 times) previous topic - next topic

NISHANTMITTAL

Hello Guys,

I am at the beginner level of Arduino and working on a project to measure the flow rate from the flow sensor.

The flow sensor came with a data sheet for Model 840205 (attached). I could read analog voltage of flow and temperature using a basic analog read program from example. But to make this into some meaning full data, we need to use data that is stored in EEPROM of the flow sensor.

can someone please help me to write a program to do so.

TheMemberFormerlyKnownAsAWOL

Quote
The EEPROM manufacturers data book will include further details on how to read data out of the ROM.
Please don't PM technical questions - post them on the forum, then everyone benefits/suffers equally

NISHANTMITTAL

Hello,

This was my first question on Arduino form and I have posted it in forum only.

The datasheet attached is all that was given by the manufacturer.

TheMemberFormerlyKnownAsAWOL

I'll try again
Quote
The EEPROM manufacturers data book
Please don't PM technical questions - post them on the forum, then everyone benefits/suffers equally

cattledog

Quote
But to make this into some meaning full data, we need to use data that is stored in EEPROM of the flow sensor.
can someone please help me to write a program to do so.
It appears that the flow sensor uses an SPI eeprom.
Table 6.2 shows the pin connections.
Table 6.4 shows the address map.

https://www.arduino.cc/en/Tutorial/SPIEEPROM

This tutorial shows how to work with an SPI eeprom. It will give you some ideas.

NISHANTMITTAL

#5
May 31, 2020, 05:32 am Last Edit: May 31, 2020, 05:56 am by NISHANTMITTAL
Hello Cattledog,

I have been following this SPI EEPROM example and modified the code as I don't want to write anything in my EEPROM. Below are the connections I have made and my program.

Sensor Pin------Arduino pin
1------------A0
2-----------A1
3--------- 5V
4-----------Gnd
5---------11
6----------13
7----------10
8--------12
9----------5V
10--------Gnd


************ CODE *************
#define DATAOUT 11//MOSI
#define DATAIN  12//MISO
#define SPICLOCK  13//sck
#define SLAVESELECT 10//ss

//opcodes
#define WREN  6
#define WRDI  4
#define RDSR  5
#define WRSR  1
#define READ  3
#define WRITE 2

byte eeprom_output_data;
byte eeprom_input_data=0;
byte clr;
int address=0;
//data buffer
char buffer [128];

void fill_buffer()
{
 for (int I=0;I<8;I++)
 {
   buffer=I;
 }
}

char spi_transfer(volatile char data)
{
 SPDR = data;                    // Start the transmission
 while (!(SPSR & (1<<SPIF)))     // Wait the end of the transmission
 {
 };
 return SPDR;                    // return the received byte
}

void setup()
{
 Serial.begin(9600);

 pinMode(DATAOUT, OUTPUT);
 pinMode(DATAIN, INPUT);
 pinMode(SPICLOCK,OUTPUT);
 pinMode(SLAVESELECT,OUTPUT);
 digitalWrite(SLAVESELECT,HIGH); //disable device
 // SPCR = 01010000
 //interrupt disabled,spi enabled,msb 1st,master,clk low when idle,
 //sample on leading edge of clk,system clock/4 rate (fastest)
 SPCR = (1<<SPE)|(1<<MSTR);
 clr=SPSR;
 clr=SPDR;
 delay(10);
 Serial.print('h');
 Serial.print('i');
 Serial.print('\n');//debug
 delay(1000);
}

byte read_eeprom(int EEPROM_address)
{
 //READ EEPROM
 int data;
 digitalWrite(SLAVESELECT,LOW);
 spi_transfer(READ); //transmit read opcode
 spi_transfer((char)(EEPROM_address>>8));   //send MSByte address first
 spi_transfer((char)(EEPROM_address));      //send LSByte address
 data = spi_transfer(0xFF); //get data byte
 digitalWrite(SLAVESELECT,HIGH); //release chip, signal end transfer
 return data;
}

void loop()
{
 eeprom_output_data = read_eeprom(address);
 Serial.print(eeprom_output_data,HEX);
 Serial.print('\n');
 address++;
 if (address == 8)
   address = 0;
 delay(500); //pause for readability
}



the output of this code is 78 (HEX).  looks like i am doing something wrong here but not sure what.

can you please help further.

cattledog

Please edit your post to place your code with the code tags as described in Item 7 of How to Use this Forum.

Without them, the forum software distorts the posted code.

NISHANTMITTAL

Here is corrected code

Code: [Select]

#define DATAOUT 11//MOSI
#define DATAIN  12//MISO
#define SPICLOCK  13//sck
#define SLAVESELECT 10//ss

//opcodes
#define WREN  6
#define WRDI  4
#define RDSR  5
#define WRSR  1
#define READ  3
#define WRITE 2

byte eeprom_output_data;
byte eeprom_input_data=0;
byte clr;
int address=0;
//data buffer
char buffer [128];

void fill_buffer()
{
  for (int I=0;I<8;I++)
  {
    buffer[I]=I;
  }
}

char spi_transfer(volatile char data)
{
  SPDR = data;                    // Start the transmission
  while (!(SPSR & (1<<SPIF)))     // Wait the end of the transmission
  {
  };
  return SPDR;                    // return the received byte
}

void setup()
{
  Serial.begin(9600);

  pinMode(DATAOUT, OUTPUT);
  pinMode(DATAIN, INPUT);
  pinMode(SPICLOCK,OUTPUT);
  pinMode(SLAVESELECT,OUTPUT);
  digitalWrite(SLAVESELECT,HIGH); //disable device
  // SPCR = 01010000
  //interrupt disabled,spi enabled,msb 1st,master,clk low when idle,
  //sample on leading edge of clk,system clock/4 rate (fastest)
  SPCR = (1<<SPE)|(1<<MSTR);
  clr=SPSR;
  clr=SPDR;
  delay(10);
  Serial.print('h');
  Serial.print('i');
  Serial.print('\n');//debug
  delay(1000);
}

byte read_eeprom(int EEPROM_address)
{
  //READ EEPROM
  int data;
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(READ); //transmit read opcode
  spi_transfer((char)(EEPROM_address>>8));   //send MSByte address first
  spi_transfer((char)(EEPROM_address));      //send LSByte address
  data = spi_transfer(0xFF); //get data byte
  digitalWrite(SLAVESELECT,HIGH); //release chip, signal end transfer
  return data;
}

void loop()
{
  eeprom_output_data = read_eeprom(address);
  Serial.print(eeprom_output_data,HEX);
  Serial.print('\n');
  address++;
  if (address == 8)
    address = 0;
  delay(500); //pause for readability
}

TheMemberFormerlyKnownAsAWOL

Quote
the output of this code is 78 (HEX). 
78 repeated eight times, or just 78?
Please don't PM technical questions - post them on the forum, then everyone benefits/suffers equally

NISHANTMITTAL

#9
May 31, 2020, 12:25 pm Last Edit: May 31, 2020, 12:29 pm by NISHANTMITTAL
it keeps on printing 78 on serial every 0.5 seconds. i guess its because of loop.

cattledog

Your code looks reasonable to me.

Can you see any sort of identification on the eeprom chip on the board? The specific manufacture and chip id might help determine any specific settings required.

I would suggest that you try different spi modes and speeds. You are using mode 0 at clk/4 (4MHz). While is is generically common, the specific eeprom may require something else. I'd try the different modes first, because an eeprom chip doesn't work at 4MHz would be unusual.


NISHANTMITTAL

Hello,

Can you please tell me exactly where I need to make changes. I will try to get EEPROM datasheet also

Thanks

cattledog

#12
May 31, 2020, 09:39 pm Last Edit: May 31, 2020, 09:41 pm by cattledog
Quote
Can you please tell me exactly where I need to make changes
You will set the values in the SPCR (SPI Control Register)  There are 4 possible modes set by bits 3 and 2. CPOL (clock polarity) and CPHA(clock phase).

There is a summary of the SPCR resister here
http://avrbeginners.net/architecture/spi/spi.html

Google search for "avr spcr spi control register" will get you more.

What Arduino are you using?
 
Quote
I will try to get EEPROM datasheet also
Good idea.

NISHANTMITTAL

Hello cattledog,


I have gone through the link you have shared, and modified my code a little bit. I found the EEPROM installed on circuit it is AT25020AN and in its datasheet, it says clock speed 20MHZ. (attached datasheet).

I modified  SPCR = (1<<SPE)|(1<<MSTR)   to   ------------->SPCR = (1<<SPE)|(1<<MSTR)|(SPR1)|(SPR1);


still, the output is 78 once and repeat after 0.5 seconds.

Code*******************
Code: [Select]


#define DATAOUT 11//MOSI
#define DATAIN  12//MISO
#define SPICLOCK  13//sck
#define SLAVESELECT 10//ss

//opcodes
#define WREN  6
#define WRDI  4
#define RDSR  5
#define WRSR  1
#define READ  3
#define WRITE 2

byte eeprom_output_data;
byte eeprom_input_data=0;
byte clr;
int address=0;
//data buffer
char buffer [128];

void fill_buffer()
{
  for (int I=0;I<8;I++)
  {
    buffer[I]=I;
  }
}

char spi_transfer(volatile char data)
{
  SPDR = data;                    // Start the transmission
  while (!(SPSR & (1<<SPIF)))     // Wait the end of the transmission
  {
  };
  return SPDR;                    // return the received byte
}

void setup()
{
  Serial.begin(9600);

  pinMode(DATAOUT, OUTPUT);
  pinMode(DATAIN, INPUT);
  pinMode(SPICLOCK,OUTPUT);
  pinMode(SLAVESELECT,OUTPUT);
  digitalWrite(SLAVESELECT,HIGH); //disable device
  // SPCR = 01010000
  //interrupt disabled,spi enabled,msb 1st,master,clk low when idle,
  //sample on leading edge of clk,system clock/4 rate (fastest)
  SPCR = (1<<SPE)|(1<<MSTR)|(SPR1)|(SPR1);
  clr=SPSR;
  clr=SPDR;
  delay(10);
  Serial.print('h');
  Serial.print('i');
  Serial.print('\n');//debug
  delay(1000);
}

byte read_eeprom(int EEPROM_address)
{
  //READ EEPROM
  int data;
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(READ); //transmit read opcode
  spi_transfer((char)(EEPROM_address>>8));   //send MSByte address first
  spi_transfer((char)(EEPROM_address));      //send LSByte address
  data = spi_transfer(0xFF); //get data byte
  digitalWrite(SLAVESELECT,HIGH); //release chip, signal end transfer
  return data;
}

void loop()
{
  eeprom_output_data = read_eeprom(address);
  Serial.print(eeprom_output_data,HEX);
  Serial.print('\n');
  address++;
  if (address == 8)
    address = 0;
  delay(500); //pause for readability
}

cattledog

Quote
I modified  SPCR = (1<<SPE)|(1<<MSTR)   to   ------------->SPCR = (1<<SPE)|(1<<MSTR)|(SPR1)|(SPR1);
This syntax makes no sense to me. What do you want the SPCR register to look like when setup as you want?

I will take a look at the data sheet you attached.

Go Up