0
\$\begingroup\$

I'm currently developing a board for my dissertation that should monitor voltage, current and power consumption of a given load. For that purpose i chose to use the Alegro chip ACS71020, the one i chose was the spi model with an IPR of 30Amp. To interface with the ACS71020 i'm using the PSoC 5lp but this shouldn't differ much from MCU to MCU.

This is the schematic for my hardware setup, i decided to use pullup resistors because the development board schematic also uses them when you try to buy the spi version.

Schematic.

I'm working on with 230V@50Hz power source (european), therefore i'm using a 2Kohm resistor for Rsense giving me a Full Scalle voltage of 550V.(this value will be needed later on) After this I connected it to the psoc using this pins (taking care to use a 3.3voltage reference for the PSoC output so that i wouldn't fry the ACS71020. PSoC Pinout

My problem here is that when measuring voltage without it connected it measures around 30Volt and when doing a practical test, using a lightbulb as the load the voltage measurements fluctuate from about 140 to 230vol which is not the correct value also the current value is always really low.

This is data i got when requesting a voltage and current readind every 4 seconds. Light bulb on Light buld off

As you guys can see if the power is off the readings although incorrect are consistent and when the power is on the readings are mostly incorrect and inconsistent both voltage and current.

Here is the code i used to get the readings.

void SPIrequestData32 (_Bool rw, uint8 addr, uint8 p, uint8 s, uint8 t, uint8 q){
/*******************************************************************
*   Requests data from and address with read or write permissions
*   and stores 32bit answer in SPI Rx buffer
*   Inputs int RW, uint8 addr Clears TxRx&FIFO
*   RW == 1 READ RW==0 Write
*   32bit answer is stored in SPI_RxDataBuffer
*******************************************************************/
        uint8 Address = 0x00;
        //clear buffers
        SPIM_1_ClearTxBuffer();
        SPIM_1_ClearRxBuffer();
        SPIM_1_ClearFIFO();   
        //Sends address with rw bit
        //uint8 Address = ((0x1E) | read);  
        if(rw==1){
             Address = ((addr) | read);
        }else if (rw == 0){
             Address = ((addr) | write);
        }
        //waits for a 32bit response = 4frames
        if(rw==1){    
        SPIM_1_WriteTxData(Address);
        SPIM_1_WriteTxData(0x00);
        SPIM_1_WriteTxData(0x00);
        SPIM_1_WriteTxData(0x00);
        SPIM_1_WriteTxData(0x00);}
        if(rw==0){    
        SPIM_1_WriteTxData(Address);
        SPIM_1_WriteTxData(p);
        SPIM_1_WriteTxData(s);
        SPIM_1_WriteTxData(t);
        SPIM_1_WriteTxData(q);}
        while(!(SPIM_1_ReadTxStatus() & SPIM_1_STS_SPI_DONE));
}

In this function i receive the address i wish to read or write to and if it's a read i just drive the line low so that the ACS71020 has de CS and CLK active. if its a write i proceed to write the byte i wish. After receiving the data from the MISO line i call the function to convert the firt 15 bytes to voltage and the next 15 bytes to current doing so with the help of the lackluster datasheet.

void V_I_RMS (){
/*******************************************************************
*   Transforms 32bit response in VRMS(V) and IRMS(A) values
*   output is global variable VRMs IRMs
*******************************************************************/
    uint8 zero = 0;
    uint8 primeiro = 0;
    uint8 segundo = 0;
    uint8 terceiro = 0;
    uint8 quarto = 0;
    uint16 V = 0;
    uint16 I = 0;
    uint16 aux = 0;
    uint16 aux2 = 0;
        for(uint8 i = 0u; i<5u; i++){
            //ignorar o primeiro
            switch(i){
            case 0: zero = SPIM_1_ReadRxData(); break;   //The first one is to be ignored
            case 1: primeiro = SPIM_1_ReadRxData(); break;
            case 2: segundo = SPIM_1_ReadRxData(); break;
            case 3: terceiro = SPIM_1_ReadRxData(); break;
            case 4: quarto = SPIM_1_ReadRxData(); break;
            default:break;               
            }
            
        }
        V = ((segundo<<8) | primeiro); //Voltage is 16bit number with 15 fractional bits
        VRMs = (fullscaleV *( (float)V / (float)0x8000) );
       
        
        I = ((quarto<<8) | terceiro);   //current is a 15bit number with 14fractinal bits
        aux = I & 0b0100000000000000;   //Mask to check if its 1.xxx or 0.xxx
        if(aux == 0x4000){ aux = 1;}
        else if (aux == 0){aux = 0;}
        aux2 = (I & 0b0011111111111111);    //checks for fractional bits
        IRMs = IPR*(aux + (aux2*Istep));      //currents is given but IPR*(unit+fraction*(2^14))
        

}

I don't understand if i'm doing anything wrong while converting or requesting data to give such bad results. If anyone ask's my SPI master block is setup in this way, refering to the datasheet it's the correct way. I've tried increasing or decreasing it's bit rate but the results i get are the same. I've also tried to change some shadow registers and the customer acess code but when i read the register aftwards it comes all messed up sometimes showing nothing but zeros sometimes showing the what i've written into them.

SPI master

This is a printscreen of my digital oscilloscope where i can see that by requesting to read register 0x1E with the 7th bit high which is the read bit it results in 0x9E(reading mode). By driving the MOSI line high or low it maintains CS and CLK working as intended.

Oscilloscope printscreen

Ok, I've done some testing and i've found out that as stated in the cover of the datasheet the power supply of your ASEK71020KMAB-090B3-I2C and your Micro-controller unit needs to be isolated. I tested this out by powering it all from a laptop using only it's battery (it shouldn't be charging otherwise it wont be isolated). This fixed my issues with random readings.

\$\endgroup\$
5
  • 1
    \$\begingroup\$ Why not post the code instead of screenshots? Where do you control the CS line? Do you have other SPI devices on bus? \$\endgroup\$
    – Justme
    Aug 1 '20 at 19:47
  • 1
    \$\begingroup\$ I'm not familiar with this i thought screenshots were good. The CS line is controlled automaticaly by the SPI module in the PSoC, there are no more devices on the bus. \$\endgroup\$ Aug 1 '20 at 20:02
  • \$\begingroup\$ How do you know it is automatically controlling it in the correct way? It must be taken low, then do the transaction you want, and then taken high. How do you make sure it does that? \$\endgroup\$
    – Justme
    Aug 1 '20 at 20:13
  • 1
    \$\begingroup\$ I have a digital oscilloscope to check the behaviour. I can post i screenshot of it. \$\endgroup\$ Aug 1 '20 at 20:13
  • \$\begingroup\$ "This fixed my issues with random readings." : If you solved the problem, please feel free to post the solution formally as an answer yourself (It is allowed by SE policy). It will help future readers. \$\endgroup\$
    – AJN
    Aug 4 '20 at 9:26
0
\$\begingroup\$

This fixed my issues with random readings.

I've done some testing and i've found out that as stated in the cover of the datasheet the power supply of your ASEK71020KMAB-090B3-I2C and your Micro-controller unit needs to be isolated. I tested this out by powering it all from a laptop using only it's battery (it shouldn't be charging otherwise it wont be isolated).

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.