Post Go back to editing

Using CN0540 and ESP32-S3 to collect IEPE accelerometer data

Category: Hardware
Product Number: CN0540

I recently acquired a CN0540 board and want to use it in my project to measure sensor data from PCB's 393A03 and 393B12 accelerometers. However, I'm using ESP32-S3 microcontrollers, which are not compatible with the board.

The thing is, I don't require much configuration of the board itself, I only wish to measure acceleration with a 200Hz maximum sampling frequency, convert using a 24 bit ADC and store the measurement values in an SD card, so I believe the default settings should do it, but I could be wrong.

Currently, I'm only connecting the ESP32 to the following pins on top of the board:
-3.3V and GROUND
-SPI interface (CS_ADC, DOUT, SDI and SCLK);
All the remaining pins, including the ones at the bottom of the board, are disconnected.

I am capable of reading and writing register values from the AD7768-1, but attempting to read the 24 bit data register only results in the value 128.00, even after connecting the sensor via SMA to the CN0540 board, which indicates that it isn't working. Moreover, in the board itself, only two LEDs light up, the FAULT LED (red) and the CC LED (blue). I know that the POWER LED (green) should also be on, but it isn't.

With this in mind, my question is: can I use this method to interface with the CN0540 board and obtain sensor data with 24 bits resolution? If yes, what connections am I missing? If not, is my only alternative buying one of the supported boards?

I hope someone can help me out!

Top Replies

  • Hi  

    To answer your main question:

    With this in mind, my question is: can I use this method to interface with the CN0540 board and obtain sensor data with 24 bits resolution? If yes, what connections…

  • Hi  

    To answer your main question:

    With this in mind, my question is: can I use this method to interface with the CN0540 board and obtain sensor data with 24 bits resolution? If yes, what connections am I missing? If not, is my only alternative buying one of the supported boards?

    The connections you have for SPI* are correct, so you will be able to communicate and collect data from the ADC. However, this reference design makes use of a level shifting DAC which subtracts the DC bias voltage of your sensor. Without this sort compensation algorithm which is loadable to the DE10Nano, the sensor signal would saturate the ADC, giving erroneous data. The algorithm itself is not very complicated (successive approximation model, like balancing a seesaw), so if you can have that and communicate with the DAC and ADC, then you get the intended performance. Still, note that the drivers working with the DE10nano controls other parts of the board, so it is still more convenient to have this platform.

    *This notes that the 3V3 label you see on the board is actually the "IOREF" node on the schematic. This powers the ADC's SPI communication block, which allows you to communicate with it. But this also means that the actual "3V3" node powering the supply rails is not powered in your setup, which is the reason why the POWER LED is off.

    Sorry about the confusion. To power all the supply rails, you can provide 3.3V to the AVDD2 test point or through the Arduino header (P2 pin 4) underneath.



  • Thank you for the quick and clear answer, Malcolm!

    I will try to implement your suggestions and report back the results afterwards.

  • Hello again!

    So, I've been trying to make this work, but so far I was unable to succeed. I will describe everything I've done, so someone may find a solution to my problem.

    As per the last response, I first connected a wire to the 3.3V pin underneath the board in order to power it. This worked, and now I have all three LEDs turned on at all times: The green POWER LED, the red FAULT LED and the blue CC LED.

    Before explaining the rest of the issue, I made a change in my connections with the CN0540 board that is important to mention. I connected two new wires to the SYNC_IN and DRDY pins, just so I could use the One Shot conversion mode of the AD7768-1, which benefits my system.

    With this in mind, and following the advice, I connected the DAC interface to my ESP32 (VCC, GND, SDA and SCL) and attempted to interface with it using I2C. I am using the library ArduinoI2C - - more specifically the 16bit functions, allowing me to send and receive I2C messages. As such, inside the setup() method of my program, I run the ADC_setup() method, which not only sets up the comunication with the ADC of the CN0540 board, but now also sends a 16bit value to the DAC address (tried both 16 and 115 addresses).

    The value I send is based on the table present on the CN0540 datasheet: 2^15-1, or 2^15-1+2^14, which are the initial values of the successive approximation algorithm. However, none of this fixed my issue.

    My main issue is the value returned from trying to read the 24 bit data register in the ADC, which always returns the same value: 8388606, or 0x7FFFFE. However, there is currently a bug where my SPI interface never returns the LSB of the register. For example, if I write 9 in the scratch pad register and read that value back, it gives me 8. This is another issue I have and don't know the cause, it might be related to SPI clock speed. As such, I'm led to believe the actual value I am reading is 0x7FFFFF, or 23 ones. Why is this happening?

    The method responsible for reading the data generated by the ADC is the ADC_readDataRegister(). I should point out that here I'm using another library, SoftwareSPI - - to interface with the board, since the other two SPI controllers of the ESP are already in use for other modules and connecting multiple devices in the same SPI line gave me trouble in the past.

    However, given that I can read ADC registers, I'd say the issue isn't there.

    Also tried replacing the accelerometer and the cable, but no change in results. Did not try to replace the board, but I don't believe that's the issue.

    I hope someone can enlighten me!

    P.S: If the links don't work, just delete the parentesis ')' at the end of the link.

  • Hi  

    Thanks for reaching out again. While the steps you are taking makes sense, these issues imply that we need to also study / debug these libraries with the same microcontroller, which we would like to step back from. For example, SPI communication may not always be completely the same across libraries / devices. It can be difficult for us to debug a platform that we are not supporting.

    If you would really like to use your platform, I think it would be best for you to migrate functions / libraries one step at a time from our supported platforms, where we can give you expert advice.

    I hope you can consider using a DE10nano.


  • Hi Malcom, and thank you again for the answer!

    I understand your point. I might try to incorporate the DE10nano into the system, but i have a few questions.

    Can you tell me how hard this would be? Can I connect the ESP32 directly to the DE10nano using any kind of interface? Is the linux driver for the CN0540 capable of sending data directly to the ESP32? Is there a better alternative board for my situation?

  • Hi  

    The DE10nano is a development kit which is Linux-based, like Raspberry Pi, and we create Linux device drivers for various ADI products. Once you have validated and are satisfied with the performance of the CN0540 using the DE10nano, you can create a simpler board for the system (i.e. vibration monitoring) using the DE10nano's FPGA (Altera Cyclone) running the same Linux driver for CN0540.

    If the ESP32 needs to be in the system, the DE10nano can communicate with it presumedly through UART, but we haven't tried it ourselves.

    ESP32 doesn't run Linux, so I don't think the CN0540 Linux driver would work directly.

    For microcontrollers like ESP32, in general we would recommend using the no-OS device drivers. However, we only have a no-OS driver for CN0540's ADC, the AD7768-1, while the DAC (LTC2606) and the CN0540 as a whole do not.

    To give some background, the DE10nano was chosen as a platform for the CN0540 and other ADI projects due its flexibility and capacity for higher data rates that otherwise could not have been possible for slower platforms like many microcontrollers, among other reasons. Some applications may only need slower ADC modes which can work with slower platforms, but then this implies the need to port the drivers to other platforms.

    As a whole, I do not have another recommendation to interface with the CN0540 aside from the DE10nano. You might arrive at something with your current code and libraries, but again we would like to step back from debugging these non-ADI supported code.


  • Hello again!

    I decided not to use the DE10nano, but have been trying to fix this issue. Turns out that the problem I was facing was the DAC not working because of bad code to implement the I2C interface. I fixed this problem and now i am getting some values at the ADC output. I even applied the equation described in the AD7768-1 datasheet to convert the output bytes to voltage, but the values are always close to negative reference, -4.22V. If i hit the accelerometer i can go to like -3 or -2 but i have to hit it hard.

    I believe this is due to the bias voltage, which I am trying to remove by reading the J2 and J3 test points in the board (the inputs to the ADC driver) and adjusting the DAC code to make J2 and J3 the same voltage (around 2.5V), like the successive approximation algorithm. The oscilloscope I'm using can only read down to mV (ex: 2.56V) so I can't effectively remove the bias voltage. I get J3=J2 on like the 7th iteration but since i don't know if the difference is positive or negative, I can´t go further.

    I would like to implement an automatic successive approximation algorithm in my code, but I would need the J2 and J3 values which are test points and not connectors. How am I supposed to obtain these values and connect them to the ESP32 ADC? I searched the schematics and found the IO5 and IO4 pins, but using the oscilloscope on these pins results in voltages of mV or uV, when J2 and J3 are around 2.5V.

    Are the IO5 and IO4 the pins I should use? And am i doing the right thing?

  • Hi  

    I have released an LTspice simulation for the CN0540, which is found here: Precision Medium Bandwidth Signal Chains | Analog Devices. Unfortunately, I just simulated it and found some convergence issues, probably due to the model updates since April 2022. Instead, I made a simplified model attached.

    CN0540 Circuit Simplified.asc

    In here, you can see a simplified formula for the required DAC output to eliminate the bias voltage:

    DAC_OUT = Vbias*0.3 + VOCM / 2.6

    where VOCM = 2.5

    The LTC2606 DAC transfer funciton is:

    From here, you can power-up the board and measure the Vbias from your accelerometer. Using this formula will still likely give you some offset, but it's a good starting point.

    But then again, it's difficult to debug without being sure of the voltages / instrument limitations. You would at least need a multi-meter for this.

    Regarding the successive approximation algorithm, you need only the output code / voltage and decide from there if you need more or less level-shifting from the DAC.

    The IO5 and IO4 can give you access to the ADC inputs, given you insert the resistors. Without a vibration, both should give you around 2.5 VOCM. Note however that tapping into this sensitive node can distort the signal.

    Wondering how you arrived at an output of -4.22V?
    What is the output code you are getting for this?
    Are you gain scaling the output to refer to the input?
    There might be an error from your use of the ADC transfer function, noting the two's complement format.


  • Hi!

    I have been hard at work trying to make this board work, and I think I've finally done it :D
    So first, I discovered that the pins IO5 and IO4 require soldering resistors in the actual board, so I followed your advice and started using the output of the ADC as a reference for the successive approximation algorithm.
    The 4.22V I got from the VREF test point using the oscilloscope, but that value might be off because the probes can be damaged, so I started using the 4.096V that is referred in the datasheet.
    Regarding the ADC, what I did to turn the codes into voltage was use the equation provided in the AD7768-1 datasheet:

    However, I had a lot of trouble understanding the process of converting the codes from two's complement to straight binary, and honestly I still don't understand how it's done. For example, the datasheet indicates that the value 0x7FFFFF in table 12 should be turned into 0xFFFFFF, but how?
    I tried many methods to implement this equation into my code, and finally found a way to correctly transform codes into voltages: I just use the two's complement code coming from the ADC instead of converting to straight binary, and in the equation I don't subtract the Midscale code (8388608). As such, my equation looks like this:

    Voltage = (Code x 2 x Vref)/2^24

    Where Code is taken directly from the ADC and Vref=4.096V.

    With this implementation, I was able to obtain the same values of voltage shown in Table 12. This means that the code 0x7FFFFF gives me +4.095999512V, 0x000001 gives +488nV, 0xFFFFFF gives -488nV and so on. Furthermore, my successive approximation algorithm can use the voltage to adjust the DAC value. On startup, with the accelerometer standing still on my desk, the algorithm can get to a voltage value of around -0.2V to -0.4V. Then, when the system is capturing data, if I start hitting the accelerometer, the voltage levels change accordingly and I get voltages between -4.096V and 4.096V.

    Really happy that I'm finally getting something out of this blue board, but please tell me if I'm doing something wrong! I would like to thank you once again for the great help, and in case more questions appear, I'll post them here!

  • Hi  

    Sounds like you got it.

    On your equation, you cannot use the ADC output code directly because it is in two's complement, but your code / implementation might already be correctly calculating in two's complement format. That's why 0xFFFFFF (twenty four 1's in binary, 16777215 in decimal) might correspond to -488nV in your system. Otherwise if I directly plug that in your formula:

    Voltage = 16777215 * 2 * 4.096 / 2^24 = 8.191V, not -488 nV.

    I find this easy to use:

    "Twos complement, for conversion purposes, consists of a binary code for positive magnitudes (0 sign bit), and the twos complement of each positive number to represent its negative... In two's complement, you must check the MSB first before multiplying the decimal code by the LSB. When MSB is 0 you can just multiply the decimal code directly by the LSB but if the MSB is 1 you need to subtract 2^N from the code, then multiply by LSB size. "

    Since MSB = 1

    Voltage = (16777215 - 2^24) * LSB = -488 nV

    You can read more ADC fundamentals on Precision ADCs Basic - Documents - Precision ADCs - EngineerZone (