Jump to content
  • 0

Pmod ISNS20 SPI Arduino


tfcb

Question

Hi,

I'm attempting to use the ISNS20 with an Arduino Uno. I am using a Sparkfun Bi-Directional Logic Level Converter to handle 5V vs 3.3V.

I'm using the source from https://www.hackster.io/58702/using-the-pmod-isns20-with-arduino-uno-0ee8db .

CS is connected to Pin 10, D0 is connected to Pin 12 and CLK is Pin 13.

I wire Black/Line to IP+ and the IP- to the Black/Line connection on an outlet. Unfortunately I get the same result if I draw current or not (using a hair dryer).

14:54:37.548 -> Courant=-33 mA
14:54:37.582 -> Courant=28 mA
14:54:37.582 -> Courant=-33 mA
14:54:37.615 -> Courant=-33 mA
14:54:37.615 -> Courant=28 mA
14:54:37.648 -> Courant=-33 mA

I don't have an oscilloscope. I do have a DMM.

Thanks,

Tim

Link to comment
Share on other sites

19 answers to this question

Recommended Posts

Hello from Germany,

following this thread for a few days becaus having same problems with measuring mA?

I build an array of 9 PmodISNS20 connected to an Arduino NANO V3 for reading the 9 valuses > combine to an string and send via RS232 to an ESP8266WiFi with display to visualize the mA / Wh every second.

Every 5 seconds i send the data over WiFi to an SQL database on server.

Everything working fine but the measuring is wrong.

Having with and without offset an value of 0.022 mA on every Pmod20ISNS >  with fuses ON or OFF!

Attached see picture of project ?

Module array.jpg

Display.jpg

Fuse box.jpg

Link to comment
Share on other sites

Hi @tfcb and @Diego,

Had an epiphany just now and figured you were owed it now in the middle of the night rather than waiting till after the Labor Day holiday in the US.

The reason the Uno isn't working is because of the required voltage translation; all of the code is working off of the 3.3V logic that the Pmod ISNS20 uses, but because the Uno uses 5V logic, this rescaling needs to be reflected in it's material as well. So any number in the code that relies on 3.3V logic being used will likely need to be scaled to 5V. I will provide an update tomorrow of how the numbers will look with this change (in general should be divide by 3.3 and multiply by 5, though that might need to be different for values that depend on specific Vrefs) and be able to formally test the changes in the office on Tuesday. 

Thanks,

JColvin

Link to comment
Share on other sites

Hi @tfcb and @Diego,

I have not been able to get the Pmod ISNS20 to work on an Arduino UNO; I have it set up so that I can simply move the connection wires from the Arduino UNO to a Digilent microcontroller (that operates at 3.3V for it's IO rather than 5V) and the module works correctly on the Digilent microcontroller but not the Uno. Originally, I had left the inputs on the ISNS20 floating, but attached the same ground source to both of them to help ensure no voltage potential was present, but to no avail. When I power cycle the Arduino Uno and restart the data collection, I get different values reported from the ISNS20 (and wildly different values, i.e. different by several amps) between each sample. I put delays in the code to ensure the data was not moving faster than the AVR could maintain and checked that the level shifter that I was using was operating as intended, but to no avail.

I wish I had better news, but I do not know what else could be done differently to make it work correctly.

Thanks,
JColvin

Link to comment
Share on other sites

On 4/2/2019 at 10:52 AM, JColvin said:

Hi @tfcb,

I am taking a look into this; I connected a level shifter of my own (Digilent's Pmod LVLSHFT rather than the Sparkfun one you linked to) to connect an Arduino Uno and Pmod ISNS20, but I too am getting strange values (no initial offset for example), so I'm debugging some more.

Thanks,
JColvin

@JColvin,

Any update on this issue? 

Thanks,

Link to comment
Share on other sites

On 4/2/2019 at 10:52 AM, JColvin said:

Hi @tfcb,

I am taking a look into this; I connected a level shifter of my own (Digilent's Pmod LVLSHFT rather than the Sparkfun one you linked to) to connect an Arduino Uno and Pmod ISNS20, but I too am getting strange values (no initial offset for example), so I'm debugging some more.

Thanks,
JColvin

 @JColvin,

Any update on this? Still hoping to use the modules.

Thanks,

Tim

Link to comment
Share on other sites

Hi @JColvin,
Actually there is an "voltage regulator" for 12V IN to 5V OUT on the display board.
I am using the 3.3V of the ESP8266WiFi on that board for the PmodISNS20 and the original 5V for the NANO V3.
Will change that to use the 5V at NANO V3 for the Pmod ISNS20 also > reduced to 3.3V over an level shifter !?
The 3.3V output is not enough stable for the 9 modules > break down to ~ 2.7V :-(

OTHER test today:
NANO V3 > 5V over USB programming connection, Pmod ISNS20 > 3.3V over power from the "testing board for Arduino`s" > GND of NANO and Pmod connected.

230V > Multimeter with power and ampere measuring > Pmod ISNS20 > different loads (Lamp, heater, hair dryer ...)

Watching the value of ""(float)2048 - (float)((MSB << 8) |LSB))"" >
At zero load > 2044.85!
Multimeter = 90 mA > Pmod = 1420.25
Multimeter = 4280 mA > Pmod = 1205.30
Multimeter = 8350 mA > Pmod = 1150.55
Linearity problem !?

Also a problem of different power source?

Sorry, should have english training :-(

Link to comment
Share on other sites

Hi @tfcb,

I am taking a look into this; I connected a level shifter of my own (Digilent's Pmod LVLSHFT rather than the Sparkfun one you linked to) to connect an Arduino Uno and Pmod ISNS20, but I too am getting strange values (no initial offset for example), so I'm debugging some more.

Thanks,
JColvin

Link to comment
Share on other sites

BTW: The Arduino NANO V3 is connected 5V at the Display who has an voltage regulator for 3.3V and 5V.

The modules are connected to the 3.3V of the regulator with same GND.

SORRY for the BIG pictures i uploaded last time :-) Should be smaller :-)

I have an loop over the 9 modules "CSpin" array for the CS pins.

Added   SPI.setBitOrder(MSBFIRST); to try if reading over SPI needs that!?

Last sample i deactivated the   //  SPI.setClockDivider(SPI_CLOCK_DIV16); // configuration of clock at 1MHz for a test !?

Last code i used:

#include <SPI.h> // call library
#include <EEPROM.h>
#define Echantillon 3000 // number of samples

String OutData;
int CSpin[9] = {2, 3, 4, 5, 6, 7, 8, 9, 10};
int MSB;
int LSB;
float valeur = 0;
float total = 0;
float totalSCHIFT = 0;
float CorrSHIFT = 0;
int milli_amps;
int Offset[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned long period = 1000;
unsigned long time_period = 0;
bool IsConn = false; // ONLY true when USB connected!
String EFB = "X";
bool newRS = false;

void setup() {
  Serial.begin(115200);
  SPI.begin(); // initialization of SPI port
  SPI.setDataMode(SPI_MODE0); // configuration of SPI communication in mode 0
  //  SPI.setClockDivider(SPI_CLOCK_DIV16); // configuration of clock at 1MHz
  SPI.setBitOrder(MSBFIRST);

  for (uint8_t thisPin = 0; thisPin < 9; thisPin++) {
    pinMode(CSpin[thisPin], OUTPUT);
    //    digitalWrite(CSpin[thisPin], HIGH);
  }
  if (IsConn) Serial.println("NANO PmodSNSI20 initialisiert");
  CheckEEP();
}

void loop() {
  time_period = millis();
  while (millis() < time_period + period) {
    if (newRS) {
      newRS = false;
      SetOffset();
    }
  }
  OutData = "";
  for (int cCS = 0; cCS < 9; cCS++) {
    total = 0.0;
    totalSCHIFT = 0.0;
    CorrSHIFT = 0.0;
    if (IsConn) totalSCHIFT = 0.0;
    for (int i = 0; i < Echantillon; i++)
    {
      digitalWrite(CSpin[cCS], LOW); // activation of CS line
      MSB = SPI.transfer(0x00); // MSBs recovery
      LSB = SPI.transfer(0x00); // LSBs recovery
      digitalWrite(CSpin[cCS], HIGH); // deactivation of CS line
      valeur = ((float)((MSB<<8) | LSB)/4096.0*3.0/0.066); // Formula ((float)((MSB<<8) | LSB)/4096.0*3.0-((float)Offset[cCS] / (float)100))/0.066
      total = total + valeur;
      if (IsConn) totalSCHIFT = totalSCHIFT + (float)((MSB << 8) | LSB);
      if (IsConn) CorrSHIFT = CorrSHIFT + (((float)2048 - (float)((MSB << 8) | LSB)) - ((float)Offset[cCS] / (float)100));
    }
    milli_amps = (int)(total / (float)Echantillon);
    if (milli_amps < 0) milli_amps  = 0;
    if (IsConn) totalSCHIFT = totalSCHIFT / (float)Echantillon;
    if (IsConn) CorrSHIFT = CorrSHIFT / (float)Echantillon;

    if (IsConn) Serial.println("PIN " + String(CSpin[cCS]) + " mA: " + String(milli_amps));
    if (IsConn) Serial.println("OFFSET " + String((float)Offset[cCS] / (float)100));
    if (IsConn) Serial.println("SCHIFT " + String(totalSCHIFT));
    if (IsConn) Serial.println("CORR SCHIFT " + String(CorrSHIFT));
    if (IsConn) Serial.println("########################");
    OutData += String(milli_amps) + ";";
  }

  Serial.print("S;");
  Serial.print(OutData);
  Serial.println("E");
}

 

FOLLOWED by routines for receiving serial input for starting the offset measuring and writing the offsets to EEPROM for loading after power loss.

Other codes i tried:

valeur = (Correction / 100) * (((100000 / 8995) * (2048 - (float((MSB << 8) | LSB)))) ); >> taken from datasheet of the module !?

valeur = (Correction / 100) * ((2048 - (float((MSB << 8) | LSB))) * 1.320); >> 20A = 20000 mA *0.066 = 1.320 !?

 

 

Link to comment
Share on other sites

Hi,

Just tested the latest update. Here is the output with nothing connected to the IP connector.  Since I'm using a Arduino Uno a https://www.sparkfun.com/products/12009 is inline to deal with 5V vs 3.3V. Any thoughts I what I might be doing wrong?

Thanks!

Tim

15:06:29.519 -> 13553 mA   |  15.83 A
15:06:29.519 -> 
15:06:29.553 -> 
15:06:29.623 -> 16967 mA   |  18.10 A
15:06:29.623 -> 
15:06:29.623 -> 
15:06:29.726 -> 13550 mA   |  12.41 A
15:06:29.726 -> 
15:06:29.726 -> 
15:06:29.829 -> 12411 mA   |  11.27 A
15:06:29.829 -> 
15:06:29.829 -> 
15:06:29.931 -> 11274 mA   |  11.27 A
15:06:29.931 -> 
15:06:29.931 -> 
15:06:30.033 -> 11274 mA   |  11.27 A
15:06:30.033 -> 
15:06:30.033 -> 
15:06:30.136 -> 11275 mA   |  12.41 A
15:06:30.136 -> 
15:06:30.136 -> 
15:06:30.238 -> 15823 mA   |  18.10 A
15:06:30.238 -> 
15:06:30.238 -> 
15:06:30.341 -> 19237 mA   |  14.69 A
15:06:30.341 -> 
15:06:30.341 -> 
15:06:30.441 -> 13552 mA   |  12.41 A
15:06:30.441 -> 
15:06:30.475 -> 
15:06:30.543 -> 11274 mA   |  11.27 A
15:06:30.543 -> 
15:06:30.577 -> 
15:06:30.645 -> 11274 mA   |  11.27 A
15:06:30.645 -> 
15:06:30.679 -> 
15:06:30.748 -> 11274 mA   |  11.27 A
15:06:30.748 -> 
15:06:30.782 -> 
15:06:30.850 -> 11274 mA   |  12.41 A
15:06:30.850 -> 
15:06:30.884 -> 
15:06:30.953 -> 15820 mA   |  15.82 A
15:06:30.953 -> 
15:06:30.986 -> 
15:06:31.055 -> 15824 mA   |  13.55 A
15:06:31.055 -> 
15:06:31.089 -> 
15:06:31.157 -> 12415 mA   |  11.27 A
15:06:31.157 -> 
15:06:31.191 -> 
15:06:31.259 -> 11274 mA   |  11.27 A
15:06:31.259 -> 
15:06:31.293 -> 
15:06:31.361 -> 11274 mA   |  11.27 A
15:06:31.361 -> 
15:06:31.395 -> 
15:06:31.464 -> 11274 mA   |  11.28 A
15:06:31.464 -> 
15:06:31.499 -> 
15:06:31.567 -> 13547 mA   |  12.41 A
15:06:31.567 -> 
15:06:31.601 -> 
15:06:31.669 -> 19238 mA   |  16.97 A
15:06:31.669 -> 
15:06:31.703 -> 
15:06:31.771 -> 16969 mA   |  13.55 A
15:06:31.771 -> 
15:06:31.805 -> 
15:06:31.873 -> 11274 mA   |  11.27 A
15:06:31.873 -> 
15:06:31.907 -> 
15:06:31.975 -> 11274 mA   |  11.27 A
15:06:31.975 -> 
15:06:32.009 -> 
15:06:32.079 -> 11274 mA   |  11.27 A
15:06:32.079 -> 
15:06:32.114 -> 
15:06:32.182 -> 11274 mA   |  11.28 A
15:06:32.182 -> 
15:06:32.215 -> 
15:06:32.283 -> 11274 mA   |  12.42 A

 

Link to comment
Share on other sites

Hi @tfcb,

I apologize for the delay; this is the material that I used for the Pmod ISNS20 with Digilent's uC32 and the Arduino IDE. I commented out the debugging material, so I would not consider this a formal release as of yet.

Spoiler

/*************************************************************************
*                   *
*  Pmod_ISNS20_Simple_Example.pde                                        *
*  - Example Sketch for Pmod ISNS20                                      *
*                                                                        *
*  Author(s): Erik Cegnar / Matt Foreman / Sudharsan Sukumar             *     
*  Author: James Colvin for demo corrections made in March 2019          *
*  Copyright (c) 2016, Digilent Inc.                                     *
*************************************************************************/
/*

  This project is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This project is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this project; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  
*/
/************************************************************************/
/*  Module Description:             */
/*                  */
/*  This sketch is an example on on how to read the current values      */
/*  from the Pmod ISNS20.                                               */
/************************************************************************/
/*  Revision History:             */
/*                  */
/*  3/1/2016 (Erik C / Matt F / Sudharsan Sukumar): Created             */
/*  3/6/2019 (James Colvin): Fixed runtime bug and conversion formula   */
/************************************************************************/
/*  Board Support: All              */
/*                  */
/*  Example Board:                                                      */
/*  chipKit Uno32/uC32                CS Pin  = pin 8                   */
/*                                    CLK Pin = pin 13                  */
/*                                    DO Pin  = pin 12                  */
/*                    *NOTE: Use 3.3v source for VCC    */
/*                                                                      */
/************************************************************************/
/*  Parameters:               */
/*                  */
/*  FILTER_FLAG:                  1 = Filter on / 0 = No filter         */
/*  NUM_READINGS:                 Number of values to be averaged       */
/*                                in filter.                            */
/*  Jumper Settings:                            */
/*                  */
/*  JP4: RG9/DIGITAL - Short middle and right pins                */
/*  JP5/JP7: MASTER - Short middle and top pins       */
/*                  */
/*                  */
/************************************************************************/

/* -------------------------------------------------------------------- */
/*              Include File Definitions                                */
/* -------------------------------------------------------------------- */
#include <SPI.h>

/* -------------------------------------------------------------------- */
/*              Local Type Definitions                                  */
/* -------------------------------------------------------------------- */

//chip select pin on the chipKIT uC32 (board dependent)
#define CS_PIN 8 

//percent correction for sensitivity error (e.g. 100 = 100%)
//**user can use reference current to calibrate this value precisely
float SENSITIVITY_CORRECTION = 100.0;

//enable/disable digital filter                                    
#define FILTER_FLAG 1  

//number of samples for filter
//**lower amount of filter readings for a faster reading
#define NUM_READINGS 10           


//offset global
float offset;
/* -------------------------------------------------------------------- */
/*              Forward Declarations                                    */
/* -------------------------------------------------------------------- */
float get_mA(void);
float get_A(void);
float get_offset(void);

/* -------------------------------------------------------------------- */
/*              Initialization and Setup Functions            */
/* -------------------------------------------------------------------- */


void setup() {
 
  Serial.begin(9600);
  SPI.begin(); 
  pinMode(CS_PIN, OUTPUT);

  Serial.println("Have nothing connected to get the offset value associated with the ACS722 removed");
  //get the offset value now
  offset = get_offset();
  Serial.println("After the offset is obtained, attach the DUT to obtain the current");
  
}

/* -------------------------------------------------------------------- */
/*              Main Loop                                   */
/* -------------------------------------------------------------------- */
void loop() {

  signed int ma = 0;
  float a = 0.0;
  //Serial.print("number of readings should be: ");Serial.println(NUM_READINGS);
  ma = get_mA();
  Serial.print(ma);               //prints mA value over serial monitor
  Serial.print(" mA   |  ");
  
  a = get_A();
  Serial.print(a);                //prints amp value over serial monitor
  Serial.println(" A");
  
  if(FILTER_FLAG == 0){
    delay(50);
  }
  Serial.println('\n');
  delay(100);
}

/************************************************************************/
/*  signed int get_mA(void)               */
/*                                                                      */
/*      Return Value:                                                   */ 
/*              float                                                   */
/*                                                                      */
/*      Description:                                                    */
/*              This function returns the value of current flow in      */
/*              milliamperes (milliamps).                               */
/*                                                                      */
/************************************************************************/
float get_mA(void)
{
  //Serial.println("inside get_mA");
  int result1;                 //first byte from ADC
  int result2;                 //second byte from ADC
  float temp_value;                  
  float total = 0.0;        //running total of filter values
  float milli_amps;       //converted value into milli amperes  
  //Serial.print("offset is: ");Serial.println(offset);
  
  if(FILTER_FLAG == 1){
    //Read the current for NUM_READINGS and then calculate an average
    //Serial.println("starting if filterflag true");
    for(int i=0; i < NUM_READINGS; i++){
      digitalWrite(CS_PIN, LOW);      //begin SPI transfer
      result1 = SPI.transfer(0x00);   //transfer first byte in
      result2 = SPI.transfer(0x00);   //transfer second byte in
      digitalWrite(CS_PIN, HIGH);     //end transfer

      /*//Debugging material
      //temp_value = (SENSITIVITY_CORRECTION / 100) * (10000  * (((result1<<8) | result2) - 2048)) / 819;  //appends the two bytes and converts their value into milliamperes
      //temp_value = ((((result1<<8) | result2) - 2048)
      Serial.print("result1 is: ");Serial.println(result1);
      Serial.print("shifted result1 is: ");Serial.println(result1<<8);
      Serial.print("result2 is: ");Serial.println(result2);
      temp_value = float((result1<<8) | result2);
      Serial.print("temp1 is: ");Serial.println(temp_value);
      temp_value = float((result1<<8) | result2)/4096.0*3.0;
      Serial.print("temp2 is: ");Serial.println(temp_value);
      temp_value = float((result1<<8) | result2)/4096.0*3.0-1.65;
      Serial.print("temp3 is: ");Serial.println(temp_value);
      temp_value = float((result1<<8) | result2)/4096.0*3.0-offset;
      Serial.print("temp3 with offset is: ");Serial.println(temp_value);
      temp_value = (float((result1<<8) | result2)/4096.0*3.0-1.65)/0.066;
      Serial.print("temp4 is: ");Serial.println(temp_value);
      temp_value = (float((result1<<8) | result2)/4096.0*3.0-offset)/0.066;
      Serial.print("temp4 with offset is: ");Serial.println(temp_value);
      */ //end of debugging material
      
      //Sensitivity correction percent * (bit result / 12 bits * 3.0V reference - calculated offset voltage)/ (0.066V per Amp ratio) * (1000 mA per Amp)
      temp_value = (SENSITIVITY_CORRECTION / 100.0) * (float((result1<<8) | result2)/4096.0*3.0-offset)/0.066*1000.0;
      //Serial.print("mA result is: ");Serial.println(temp_value);
      //Serial.println();

      //summing the parts
      total = total + temp_value;
      //Serial.print("total is: ");Serial.println(total);
    }
    //calculating the average
    milli_amps = total / NUM_READINGS; 
    //Serial.print("mA average is: ");Serial.println(milli_amps);
    //Serial.println("leaving if flilterflag true");
  }
  
  else{
    //No filter or averaging, single sample
    //Serial.println("filterflag false start");
    digitalWrite(CS_PIN, LOW);      //begin SPI transfer
    result1 = SPI.transfer(0x00);  //transfer first byte in
    result2 = SPI.transfer(0x00);  //transfer second byte in
    digitalWrite(CS_PIN, HIGH);     //end transfer

    //wrong equation that was orignally used
    //milli_amps = (SENSITIVITY_CORRECTION / 100) * (10000  * (((result1<<8) | result2) - 2048)) / 819;  //appends the two bytes and converts their value into milliamperes
    
    //Sensitivity correction percent * (bit result / 12 bits * 3.0V reference - calculated offset voltage)/ (0.066V per Amp ratio) * (1000 mA per Amp)
    milli_amps = (SENSITIVITY_CORRECTION / 100.0) * (float((result1<<8) | result2)/4096.0*3.0-offset)/0.066*1000.0;
  }
  return milli_amps;
}

/************************************************************************/
/*  float get_A(void)               */
/*                                                                      */
/*      Return Value:                                                   */ 
/*              float                                                   */
/*                                                                      */
/*      Description:                                                    */
/*              This function returns the value of current flow in      */
/*              amperes (amps).                                         */
/*                                                                      */
/************************************************************************/
float get_A(void)
{
  int result1;           //first byte from ADC
  int result2;           //second byte from ADC
  float temp_value;      
  float total = 0;       //running total of filter values
  float amps;            //converted value into amperes
  
  if(FILTER_FLAG == 1){
    //Read the current for NUM_READINGS and then calculate an average
    for(int i=0; i < NUM_READINGS; i++){
      digitalWrite(CS_PIN, LOW);      //begin SPI transfer
      result1 = SPI.transfer(0x00);   //transfer first byte in
      result2 = SPI.transfer(0x00);   //transfer second byte in
      digitalWrite(CS_PIN, HIGH);     //end transfer
    
      //wrong equation that was orignally used
      //temp_value = (SENSITIVITY_CORRECTION / 100) * (10.0 * (((result1<<8) | result2) - 2048.0) / 819.0);  //appends the two bytes and converts their value into amperes
      
      //Sensitivity correction percent * (bit result / 12 bits * 3.0V reference - calculated offset voltage)/ (0.066V per Amp ratio)
      temp_value = (SENSITIVITY_CORRECTION / 100.0) * (float((result1<<8) | result2)/4096.0*3.0-offset)/0.066;
      total += temp_value;
    }
    amps = total / NUM_READINGS; 
  }
  
  else{
    digitalWrite(CS_PIN, LOW);      //begin SPI transfer
    result1 = SPI.transfer(0x00);  //transfer first byte in
    result2 = SPI.transfer(0x00);  //transfer second byte in
    digitalWrite(CS_PIN, HIGH);     //end transfer
    
    //wrong equation that was orignally used
    //amps = (SENSITIVITY_CORRECTION / 100) * (10.0 * (((result1<<8) | result2) - 2048.0) / 819.0);  //appends the two bytes and converts their value into amperes
    
    //Sensitivity correction percent * (bit result / 12 bits * 3.0V reference - calculated offset voltage)/ (0.066V per Amp ratio)
    amps = (SENSITIVITY_CORRECTION / 100.0) * (float((result1<<8) | result2)/4096.0*3.0-offset)/0.066;
  } 
  return amps;
}

/************************************************************************/
/*  signed int get_offset(void)               */
/*                                                                      */
/*      Return Value:                                                   */ 
/*              float                                                   */
/*                                                                      */
/*      Description:                                                    */
/*              This function returns the offset value of the Pmod      */
/*              ISNS20 with no current flow. Newly created for          */
/*              for updated demo.                                       */
/*                                                                      */
/************************************************************************/
float get_offset(void)
{
  //Serial.println("inside get_mA");
  int result1;                 //first byte from ADC
  int result2;                 //second byte from ADC
  float temp_value;                  
  float total = 0.0;        //running total of filter values
    
  
  if(FILTER_FLAG == 1){
    //Read the current for NUM_READINGS and then calculate an average
    //Serial.println("starting if filterflag true");
    for(int i=0; i < NUM_READINGS; i++){
      digitalWrite(CS_PIN, LOW);      //begin SPI transfer
      result1 = SPI.transfer(0x00);   //transfer first byte in
      result2 = SPI.transfer(0x00);   //transfer second byte in
      digitalWrite(CS_PIN, HIGH);     //end transfer
    
      /*Debugging material
      //temp_value = (SENSITIVITY_CORRECTION / 100) * (10000  * (((result1<<8) | result2) - 2048)) / 819;  //appends the two bytes and converts their value into milliamperes
      //temp_value = ((((result1<<8) | result2) - 2048)
      Serial.print("result1 is: ");Serial.println(result1);
      Serial.print("shifted result1 is: ");Serial.println(result1<<8);
      Serial.print("result2 is: ");Serial.println(result2);
      temp_value = float((result1<<8) | result2);
      Serial.print("temp1 is: ");Serial.println(temp_value);
      temp_value = float((result1<<8) | result2)/4096.0*3.0;
      Serial.print("temp2 is: ");Serial.println(temp_value);
      temp_value = float((result1<<8) | result2)/4096.0*3.0-1.65;
      Serial.print("temp3 is: ");Serial.println(temp_value);
      temp_value = (float((result1<<8) | result2)/4096.0*3.0-1.65)/0.066;
      //Sensitivity correction percent * (bit result / 12 bits * 3.0V reference)
      temp_value = (SENSITIVITY_CORRECTION / 100.0) * (float((result1<<8) | result2)/4096.0*3.0);
      Serial.print("offset is: ");Serial.println(temp_value);
      Serial.println();
      */

      //summing the parts
      total = total + temp_value;
    }
    //calculating the average
    offset = total / NUM_READINGS; 
    //Serial.println("leaving if flilterflag true");
  }
  
  else{
    //No filter or averaging, single sample
    //Serial.println("filterflag false start");
    digitalWrite(CS_PIN, LOW);      //begin SPI transfer
    result1 = SPI.transfer(0x00);  //transfer first byte in
    result2 = SPI.transfer(0x00);  //transfer second byte in
    digitalWrite(CS_PIN, HIGH);     //end transfer
    
    //Sensitivity correction percent * (bit result / 12 bits * 3.0V reference)
    offset = (SENSITIVITY_CORRECTION / 100.0) * (float((result1<<8) | result2)/4096.0*3.0);
  }
  return offset;
}

 

Let me know if you have any questions.

Thanks,
JColvin

Link to comment
Share on other sites

Hi @tfcb,

I apologize for the delay. The data lines are not 5V tolerant; they will only work reliably in the 3V to 3.6V voltage range.

As for the Pmod ISNS20, it seems that the demo code that was posted on the Resource Center was an old version that still has some bugs in it making it unusable. I am working on an updated version that correctly calculates the measured milliamps and amps as well as tests for the the initial offset error (which according to the ACS722 datasheet likely has an offset voltage of somewhere in the range of +/-12 mV or +/- 0.18A with the 66mV/A typical sensitivity) that will be used to get more accurate readings.

Thank you,
JColvin

Link to comment
Share on other sites

I ran the supplied code on an Arduino Uno using a level shifter. The output doesn't make any sense to me. Why are the mA and A results so different? Based on the use of a DMM the A should be approx 13.

Given the for loop wouldn't work on Arduino 1.8.8 I'm wondering if anyone has ever used this part successfully. I appreciate your insight on getting this to work.

Quote


21:03:59.722 -> -3 mA   |  14.91 A
21:03:59.790 -> -17 mA   |  15.74 A
21:03:59.824 -> 27 mA   |  16.07 A
21:03:59.894 -> 16 mA   |  15.56 A
21:03:59.928 -> 21 mA   |  13.81 A
21:03:59.996 -> -37 mA   |  10.92 A
21:04:00.029 -> -34 mA   |  7.39 A
21:04:00.099 -> 3 mA   |  -21.73 A
21:04:00.133 -> 14 mA   |  -24.97 A
21:04:00.200 -> -7 mA   |  -15.56 A
21:04:00.234 -> -5 mA   |  -18.75 A
21:04:00.302 -> -22 mA   |  -24.99 A
21:04:00.336 -> 3 mA   |  -25.01 A
21:04:00.404 -> 18 mA   |  -20.24 A
21:04:00.439 -> 31 mA   |  -21.51 A
21:04:00.508 -> -10 mA   |  -22.08 A
21:04:00.541 -> 8 mA   |  -22.66 A
21:04:00.609 -> 1 mA   |  -22.27 A
21:04:00.643 -> -35 mA   |  -21.73 A
21:04:00.713 -> -10 mA   |  -12.20 A
21:04:00.747 -> -33 mA   |  -8.29 A
21:04:00.781 -> 37 mA   |  -4.85 A
21:04:00.850 -> -27 mA   |  -1.34 A
21:04:00.884 -> 28 mA   |  2.17 A
21:04:00.952 -> -4 mA   |  5.09 A
21:04:00.987 -> 10 mA   |  7.94 A
21:04:01.056 -> 6 mA   |  10.27 A
21:04:01.090 -> -11 mA   |  12.49 A
21:04:01.159 -> -32 mA   |  14.11 A
21:04:01.193 -> 37 mA   |  15.23 A
21:04:01.261 -> -25 mA   |  15.91 A
21:04:01.296 -> -15 mA   |  16.01 A
21:04:01.364 -> 7 mA   |  15.20 A
21:04:01.398 -> -28 mA   |  13.04 A

 

 

Link to comment
Share on other sites

Are the data lines on the ISNS20 5v tolerant? The "resource center" isn't exactly clear. From what I can tell the various data lines on the Arduino Uno are all 5v.  Obviously 3.3v will be provided to VCC. Thanks.

BTW, as I understand, this for statement: 

for(int i; i < NUM_READINGS; i++)

should really be:

for(int i=0; i < NUM_READINGS; i++)

otherwise, the for loop might only run once (if lucky) as the variable "i" is undefined on the first run and might remain >= NUM_READINGS thereafter. The same version of gcc produces different results when executed on ARM or x86_64. More details than I understand at: https://stackoverflow.com/questions/4532871/define-integer-int-whats-the-default-value

 

Link to comment
Share on other sites

Hi @tfcb,

Here is the PmodISNS20 resource center.  I altered the  INO from the MPIDE example without a shield to use the SPI library instead of the  DSPI library and have attached it below. It compiles without issue but is untested. You will need to alter the CS_PIN to reflect the cs pin on your microcontroller.   

thank you,

Jon

Pmod_ISNS20_example.zip

Link to comment
Share on other sites

FWIW, the following python program, based on this code: https://github.com/DesignSparkrs/DesignSpark.Pmod/blob/master/DesignSpark/Pmod/ISNS20.py

#!/usr/bin/python

import spidev
import time

spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 100000
spi.mode = 0b00
try:
    while True:
        resp = spi.xfer2([0x00, 0x00])
        w = resp[0]
        w <<= 8
        w |= resp[1]
        refV = 3.3
        lsb = refV/4096
        mV= (w-2048)*lsb*1000
        amps = mV/66
        print amps
        time.sleep(1)
except KeyboardInterrupt:# Ctrl+C pressed, so...
    spi.close()

produces:

-0.048828125
15.2221679687
16.1010742188
13.76953125
5.50537109375
-3.6376953125
-11.2182617188
-15.4296875
-15.576171875
-8.69140625
1.025390625
9.89990234375
14.8559570312
15.7836914062
9.0087890625
-1.318359375
-10.595703125
-0.048828125
-0.048828125

 

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...