Go Down

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

NISHANTMITTAL

Hello,

I corrected the syntax and got different results as below:

correct syntax------ SPCR = (1<<SPE)|(1<<MSTR)|(0<<CPOL)|(1<<CPHA)|(1<<SPR1)|(0<<SPR0);

Input                                                Output
(0<<CPOL)|(0<<CPHA)                    78
(0<<CPOL)|(1<<CPHA)                     FF
(1<<CPOL)|(0<<CPHA)                      BC
(1<<CPOL)|(1<<CPHA)                     78


I will explain my project again below:
I have an airflow sensor that I want to use for airflow measurement using Arduino. This sensor comes with factory-set calibration which is stored in EEPROM.

In order to get the correct flow rate, I need to read calibration data and use it for flow rate calculations.

cattledog

From what I read in the data sheet, the eeprom will work in mode 0 or mode 3 at 4Mhz. I would therefore set SPCR as you originally had it

Code: [Select]
SPCR = (1<<SPE)|(1<<MSTR);

The problem that I see is that the tutorial was based on a larger eeprom than is on your device.  There is only an 8 bit address (one byte), and not a 16 bit (2 byte) address.

Try to modify the read function to reflect that

Code: [Select]
byte read_eeprom(byte EEPROM_address)
{
  //READ EEPROM
  int data;
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(READ); //transmit read opcode
  //spi_transfer((char)(EEPROM_address>>8));   
  //spi_transfer((char)(EEPROM_address));
  spi_transfer(EEPROM_address);           
  data = spi_transfer(0xFF); //get data byte
  digitalWrite(SLAVESELECT,HIGH); //release chip, signal end transfer
  return data;



NISHANTMITTAL

Helle Cattledog,

I modified the code as per your suggestion and now i am getting below data output in Dec.

120
121
123
124
125
126
127

and it repeats

cattledog

In reference to the the EEPROM Data Map of the Flow Sensor, (attachment in the first post) its not clear what you are seeing.

The sequential values certainly would appear to be wrong, but I don't see what is incorrect about the reading routine. However, I'm not very experienced with SPI.

I would suggest that you print address 0 through 15 to see if you can make more sense of the return values. It will be easier to deal with the values in HEX so please print them out in HEX.

I have cleaned up the code a bit, and made it consistent with all the values being typed as byte and removing the unused material.

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 address=0;

byte spi_transfer(byte 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);
  delay(10);
  Serial.print('h');
  Serial.print('i');
  Serial.print('\n');//debug
  delay(1000);
}

byte read_eeprom(byte EEPROM_address)
{
  //READ EEPROM
  byte data;
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(READ); //transmit read opcode
  spi_transfer(EEPROM_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(address);
  Serial.print('\t');
  Serial.print(eeprom_output_data,HEX);
  Serial.print('\n');
  address++;
  if (address == 16)
    address = 0;
  delay(500); //pause for readability
}

NISHANTMITTAL

Can anyone please help further to understand this data or improve the data. i really need to do this.

cattledog

Quote
Can anyone please help further to understand this data or improve the data. i really need to do this.
What output did you see with the code posted in reply #18?

NISHANTMITTAL

Below is the output from code in #18

0   7F
1   78
2   79
3   7A
4   7B
5   7C
6   7D
7   7E
8   D2
9   9
10   2D
11   0
12   7
13   D8
14   3
15   13

cattledog

I can't make much sense of the data. The model and number and serial number are not what they should be.

The only thing that seems somewhat normal is the revision and year/month/day of calibration.
 
Revision  in address 10  ascii char in decimal
 45 = '-'  (the '-' actually appears as one of the possible revisions)

Year in address 12 (?is this too old?)
7D8 = 2008

Month in address 14
3  March

Day in address 15
13   13th

I am out of ideas.  :(

Perhaps you can work with technical support at TSI, given that you have identified the eeprom, and have code which appears to read the values, but does not return what is expected.


NISHANTMITTAL

#23
Jun 02, 2020, 02:15 pm Last Edit: Jun 02, 2020, 02:19 pm by NISHANTMITTAL
Hello CattleDog,


Finally, I have some success with data. I modified the code a little bit to read data up to 255 addresses. Attached Putty file for the output data.

After that, I did the conversion of HEX output data using different conversion methods as described in the TSI datasheet. The results are in an Excel sheet.

Now the problem is how to make the code all this sorting and conversion on its. I have done all this bit by bit.


NISHANTMITTAL

#24
Jun 02, 2020, 02:42 pm Last Edit: Jun 02, 2020, 03:03 pm by NISHANTMITTAL
excel file

cattledog

#25
Jun 02, 2020, 05:38 pm Last Edit: Jun 02, 2020, 05:39 pm by cattledog
Quote
Finally, I have some success with data. I modified the code a little bit to read data up to 255 addresses. Attached Putty file for the output data.
After that, I did the conversion of HEX output data using different conversion methods as described in the TSI datasheet. The results are in an Excel sheet.
Excellent work. +1 Karma point for you. You are making good progress.

I gave up when the Serial number and model number didn't match, but its clear that there is useful data in the eeprom and you are likely reading it correctly.

One thing I notice is that when you do the ieee-754 float conversions you need to be sure that you are entering the full 4bytes with leading zeros.

For example
K1, Temperature compensation coefficient
address20
3B9D86 IEEE float 5.4748E-39

But if the value to convert is entered as 3B09D806 you get
0.002103325 which is very close to the data sheet example.

K3 is similar, and I would suggest that you review all the float conversions which you have highlighted in yellow which appear to be wrong.

NISHANTMITTAL

Ok. I will do that and get back with new result.

Meanwhile, Can you please help to do sorting of this data in code with conversion of it.

Need to run this only once and in loop will write code to measure voltage and do calculation.

cattledog

Quote
Meanwhile, Can you please help to do sorting of this data in code with conversion of it.
I would suggest that you run through a reading and conversion manually following the procedure of section 6.5 to get a feel for the situation and what exactly is needed.

For example, getting the gas temperature from the voltage with the Temperature conversion table may be an issue. Does your work require the full range of temperature? What is the actual application for the flow meter?

It may be more simple to hard code the factors required than to read the eeprom at the start of each run.


NISHANTMITTAL

Hello,

I did the correction during IEEE conversion and now the table looks perfect. (attached).

Regarding your next suggestion, I have already done the calculations from the voltage reading of temp. and flow and they look reasonable.

For me, the temperature range will be 25-40 degC.

The application is to measure the flow passing through masks during their particle filtration effiecency testing. The reason we need to read the EEPROM is that every sensor comes with its own calibration data.

so if someday one sensor goes bad, then need to do this entire exercise again to get correct flow values or let code do this even if the sensor is replaced in the future.

Thanks for your so much help

cattledog

#29
Jun 02, 2020, 07:31 pm Last Edit: Jun 02, 2020, 07:36 pm by cattledog
Quote
The reason we need to read the EEPROM is that every sensor comes with its own calibration data.
so if someday one sensor goes bad, then need to do this entire exercise again to get correct flow values or let code do this even if the sensor is replaced in the future.
OK, I didn't realize that you had a possible need for more than the unit you already have.

Quote
I did the correction during IEEE conversion and now the table looks perfect. (attached).
Does all the data look correct except for the model and serial number? If so, this issue is definitely worth a conversation with TSI.

I'm not certain what you need in code. Do you just need to fill in the table you attached in the last post with data read from the eeprom?

Address table for Vf,A,B,C


You know how to read the eeprom, and how to convert what fields you need to floats so I suggest that you try and write the code.

I would suggest that a first effort might be to think that you only have the one unit with known values, and how you would program for that, without having to read and fill those values from the eeprom.

Go Up