[AmpeROSE] Field-Programmable Gate Amperose

Hello everyone,

In this post I’d like to elaborate on how AmpeROSE’s FPGA component will operate, in the configuration where it actively participates in the automatic calibration and data acquisition. You may also want to refer to my previous post on this subject.

Automatic Calibration

When we were performing SPICE simulations of our measurement circuit, we observed the following phenomenon that led us away from thinking of implementing the calibration logic as a synchronous state machine (namely, a bidirectional shift register):

  • If the frequency of the clock driving the state machine was too elevated (>1MHz), the output of any comparators going high would very often cause the state machine to go to the corresponding extreme measurement range, even when stopping at the middle range would be the correct thing to do. This, in turn, caused the other comparator output to go high, and the state machine would oscillate. The cause of this exagerated reaction was that the state machine performed the second change in calibration before the rest of the circuit had time to properly react to the first change, and reach a new burden voltage corresponding to the current measurement range.
  • On the other hand, if the clock frequency was reduced to allow for the reaction time of the circuit after a state change (according to our simulations, about 2.5 us on the worst case, owing to the capacitances of the switches in the shunt selector), then a sudden peak in burden voltage that happened to take place just after a rising clock edge would go untreated for a very long time.

There is actually a way to address these issues without abandoning the idea of a synchronous implementation: a state machine clocked at a high frequency, which allows for a short reaction time, associated with a down-counter. Whenever a state change occurs, the down-counter is loaded with a value proportional to the reaction time allowed to the circuit, and further state changes are blocked up until the counter reaches 0. This is the strategy that I followed for implementing our calibration logic in SystemVerilog.

In terms of what exactly is the “high frequency” that should be used to clock our state machine and the counter, we calculated that in most extreme situation that still falls in our expected operating conditions (up to 300 mA drawn by the device under test (DUT), which has a bulk capacitance of 500nF) the DUT’s bulk capacitance should be able to hold the drop in the DUT’s supply voltage under 1V for about 1.66us, so we should, at the very least, react faster than this. Fortunately, Quartus indicates that maximum clock frequency for the current version of the calibration circuit is 111MHz, so we should be able to even approach the reaction time of our hardware comparators (5ns) if this proves to be necessary.

Regarding how the clock will be supplied to the calibration state machine, one of the dedicated clock inputs for the FPGA is connected to a pin of the uC which can be configured as the master clock of a Serial Audio Interface. Such a master clock signal can receive the output of the uC’s PLLI2S phase-locked loop, which we are not otherwise using in our design. This affords us a great flexibility in terms of choosing the clock frequency.

Context bits and SPI

When our external ADC signals that a new measurement is available, the FPGA “takes a snapshot” of the calibration state, of the context bits and of a bit indicating whether the calibration changed since the last measurement (which is then reset), and places it in an 8-bit register.

The “data ready” signal from the ADC is also transported to the microcontroller (uC), which should begin a SPI read of 32 bits. For the first 24 bits, the FPGA simply transports the signals between the uC and the ADC, so the 24-bit voltage measurement can be read. For the last eight bits, on the other hand, the FPGA inserts the bits from the “snapshot” on the MISO line, one per cycle of the serial clock. Thus, the uC receives the complete set of 32 bits corresponding the measurement (24 for the voltage measurement, 5 for the context and 3 for the automatic calibration) by the end of the SPI read.

How to test it all

I put together a straightforward testbench using Verilator and systemC. This testbench has simple systemC threads and methods playing the role of the components of the system (ADC, uC, comparators) which communicate through signals between themselves and to a systemC model of our FPGA, generated by Verilator from the SystemVerilog code.

Periodically, the uC thread determines a 32-bit measurement that should be obtained, and communicates it to the other threads, which cooperate to create the conditions for it to be produced (the ADC thread signals that is has completed its measurement and sends the most significant 24 bits of the 32, the comparators method react to the switch outputs of the FPGA model as if the correct range to be reached is the one described by the two least significant bits of the 32, etc.).

When the adc thread signals that a measurement is ready, the uC thread performs a SPI read, where the FPGA model plays the role described in the previous section. If the 32 bit reading obtained from this transaction is different from what was expected, the simulation returns an error. This testbench is currently passed by the SystemVerilog code.

How to proceed from here

The next immediate steps would be to improve the testbench to make it more realistic, and then to test the SystemVerilog code using a real FPGA and a microcontroller, such as the DE1-SoC boards present in our lab and our development board, respectively. After we receive our PCB, we should strive test it with our actual uC and FPGA as soon as possible.

[AmpeROSE] Recalibrating our Architecture

Hello, everyone!

In this post, I’d like to discuss a final significant change that our architecture for AmpeROSE underwent in the end of December.

The calibration problem

As you may recall, a fundamental task for AmpeROSE is to perform “automatic calibration”, controlling in real time the value of its shunt resistance, which is used to convert the current drawn by the device under test (DUT) into a tension that is amplified and measured by an ADC. Each possible value for the shunt corresponds to a range of current values that may be effectively measured with it. Having an inadequate shunt value at a given time can cause the following negative consequences:

  1. If the current is too small for the shunt (there’s a larger available value for the shunt that we should be using), we lose precision.
  2. If the current is too big for the shunt (there’s a smaller available value for the shunt that we should be using), we lose measurements, as the reading will just be stuck at the maximum value for the measurement range corresponding to the current shunt. More importantly, we risk having a brownout on the DUT if the burden voltage becomes large and the situation persists for longer than the DUT’s power supply circuit can handle.

You may consult these two previous posts (1, 2) to review our process for arriving at the automatic calibration scheme we initially based our schematics and PCB design on. Here is a high-level view of it, with the calibration circuit in the center:

In this configuration, hardware comparators are used to generate signals that indicate whenever the amplified shunt voltage has surpassed the upper limit for the current measurement range (VIN>VON), or gone below its lower limit (VIN<VOFF). A third comparator determines whether the burden voltage (voltage on the shunts) has surpassed its maximum allowable value, its output being ALERT. These outputs are fed into a circuit composed of discrete ICS (NAND and NOT gates, SR latches and delay blocks) that implements the calibration logic and generated two outputs (SW1 and SW2) which contror transistor switches which may be used to connect and disconnect resistor in parallel with the shunt, thus changing its value.

In this configuration, it is the microcontoller’s job to read each mesurement from the ADC when it’s ready, through SPI, and sample values of the calibration outputs and of the context bits to associate with the measurement. It also determines the reference voltages for the comparators using its digital to analog converters and controlling a potentiometer.

In the course of the elaboration of our printed circuit board (PCB), this approach for the calibration circuit proved to be problematic, in particular the placing and routing of the different ICs, some of them containing several logic gates that would , not to mention the difficulty of reasoning about the timing of the logic signals. More importantly, the calibration logic would be locked into what is determined by the discrete ICs placed on the PCB, and would be impossible to correct if tests with the finished PCB revealed that corrections would be in order.

In view of these issues, our supervisors encouraged us to consider two alternative approaches that would grant us more flexibility and could be implemented more expediently:

Calibrate using a FPGA

This approach uses a small field-programmable gate array – FPGA (small in terms of package size/pin numbers, and in terms of number of interal logic cells) to implement the calibration logic and generate the SWx outputs. The calibration circuit would be described using a hardware description language such as SystemVerilog, which we have employed often in our embedded systems education, and could be corrected by reprogramming the FPGA through JTAG.

Additionally, we envision using the fpga to read the ADC measurement and the context bits, and prepare and transmit the complete measurement word to the microcontroller though SPI.

Calibrate using the microcontroller

In this approach the outputs of the comparators would be connected to microcontroller pins and would generate fast interrupts, whose service routines would implement the calibration logic and update the shunt control signals.

This design has the advantage of simplifying even more the PCB, and would take advantage of the relatively powerful microcontroller we’re using in our design. On the other hand, performing the calibration does represents a significant burden on microntroller if compared with the circuit with the FPGA, especially because it will also be managing an Ethernet connection.

And the winner is…

Neither! I mean, both! Our PCB will contain a MAX3000A fpga with 44 pins and 64 macrocells, but the components have been placed and routed in such a way that it will be possible to implement either of the designs present above in the PCB, just by reprogramming the microcontroller and the FPGA. The calibration using the FPGA will work essentially as described previously, while for the calibration using the microcontroller, the FPGA will be programmed to simply transmit signals transperantly between the microcontroller and other components in the board.

This strategy will allow us to evaluate the feasibility of both strategies, with the goal of determining which would be more interesting for a more mature version of AmpeROSE. I’m currently working on the SystemVerilog code for the calibration using FPGA, which should then be simulated and tested so we can be confident it’s likely to work when we receive our PCB.

[AmpeROSE] – Pining for a PCB

Hello, everyone!

We’ve been really focused on making sure the physical circuit for AmpeROSE is the best it can be, as it is, in many ways, the most delicate part of our project. In this post, I’d like to talk about how our microcontroller will interact with the rest of our custom printed circuit board, some preliminary planning we’ve done on the firmware, and some interesting interactions between these two tasks.

The Firmware

We have decided to use the ChibiOS real-time operating system to support our embedded code, as we are already familiar with it, and it offers what we need in terms of device drivers and RTOS features (threads, synchronization primitives, etc.) . Our application code will be organized around three main threads, corresponding to the three main tasks performed by AmpeROSE:

  • A data acquisition thread which receives measurements through an interrupt-driven process, detailed further along in this post, applies any necessary signal processing and logical decisions (such as discarding the measurement immediately after a change in measurement) and passes it along to the transmission thread.
  • A transmission thread responsible for sending the measurements to the user interface through Ethernet or USB, or to the SD card through SDIO.
  • A command reception thread responsible for receiving commands from the user interface and controlling the whole program to follow them.

AmpeROSE’s Microcontroller

As you may remember from a previous post, we’ll now be using a STM32F767VIT6 as our microcontroller (or μC). It comes in a low-profile quad flat packaging (LQFP), with 100 pins to interface with the rest of the circuit. You can see its dimensions in milimeters on this image from page 54 of the datasheet.

Of the 100 pins, 16 are reserved for connecting the μC to various voltages (VSS, VDD, VDDA, VCAP…), one is a reset pin and one is used to tell the μC which boot address to use between two programmed options. The 82 other pins may either be used as general-purpose input/output or set to perform a number of alternate functions, the particular subset of alternate functions available being specific to each pin. These pins represent our “budget” for connecting the STM32F767 to the different peripherals on the board, including the current measurement circuit.

Below, the impact of the different peripherals we plan to include in AmpeROSE on this “budget” is discussed:


The STM32F767 includes a 10/100 MAC controller, which must be connected to an external ethernet transceiver (which implements the physical layer of communications). We’ll be using a LAN8742A connected to the μC through a Reduced Media-Independent Interface (RMII). Compared to the standard MII, RMII uses 9 signals instead of 18, but works at a clock frequency of 50MHz instead of 25MHz, which means we have to be particularly careful with the signal integrity of these connections. For each of the 9 RMII signals, only one pin of our μC is capable of performing its function, so we did not have much choice on this matter.

SD Card

The STM32F767 includes two interfaces for exchanging data with SD cards, but one of them conflicts (= needs some of the same pins) with the Ethernet, so we’ll be using the other one on a 4-data pins configuration (which means 6 pins are used, 4 for data + one for clock and one for commands).


The STM32F767 includes two USB interfaces: one for Full-Speed usb connections, for which a transceiver is also included in the packaging, and one for High-Speed connections. In order to use the High-Speed connection, it would be necessary to have an external transceiver, but some of the 12 (!) pins that must be used for connecting the transceiver to the μC are already taken by the Ethernet, so we’ll be working at Full Speed. As AmpeROSE will only ever operate as a USB device, there’s no need to use the ID usb signal, so only two pins (for the DM and DP signals) are needed.


We’ll be using a 32.7Hz quartz and a 20MHz quartz to provide clock sources for the μC, so the 4 pins that may be configured as connections for such oscillators will be used for this.

Context Bits

Six pins will be inputs for receiving context signals from the device under test, through a connector.


After performing a set of SPICE simulations, we have finally settled on an automatic calibration scheme, which will be detailed on another post (spoiler for those following at home: it will be a modified version of the circuit with RS latches). The simulations have also led us to reduce the number of measurement ranges we’ll be working with from 4 to 3, which means that we’ll have only two switches determining which resistors the current from the device under test will go through.

To survey the state of the control signals going from the automatic calibration circuit to these two switches (and thus, the state of the calibration), two pins will be used as inputs. It would be desirable that the μC keeps track of the state of the calibration whenever it changes, rather than just sampling it when a new measurement is made, to avoid the risk of doing this sampling right during a transition and ending with a spurious value.

Our strategy for doing so is to configure the two pins as interrupt sources, which will be activated at rising or falling edges of their input signals. In our μC, the GPIO pins with names ending with numbers from 5 to 9 all activate the same IRQ, as do the pins with names ending with numbers 10 to 15 . We will connect the calibration outputs to two pins in the first group (5 to 9), and use the common IRQ callback for the group to read the state of the pins and update a variable in memory with them.

Additionally, a mechanism for the processor to preempt the automatic calibration and assume direct control of the switches is also needed for our initial calibration process. The schema below, which ties up another 3 pins, appears to be the best solution:

The initial calibration also makes it necessary to have an output pin for controlling whether the shunt resistance receives current from the device under test or from our current mirror.

Finally, as we’ll have a mechanism for the processor to control the switches directly, our supervisors have instructed us the leave open the possibility of doing the calibration through software. This implies that the processor must have a way of knowing when the voltage on the shunt has reached a lower or upper limit and must be changed. Two options for doing so are using the internal adc for reading the voltage output by our amplification stage (needs 1 pin) and reading the outputs from the two comparators of the calibration circuit (needs 2 pins). We have enough free pins for doing either, or even both, strategies.


In order to control the potentiometers present in the circuit, a 2-wire I2C interface will be used.

Analog-to-Digital Converter

We’ve chosen the AD7766 as our external ADC. The protocol for reading data from it is identical to SPI, so one of the SPI interfaces from μC will be connected to it. As this connection will only ever transmit data from the slave (the ADC) to the master (the μC), and contains a single slave, only two SPI signals are needed: CLK and MISO.

Two further signals are needed: one is a GPIO input configured as an interrupt source, connected to the DREADY pin of the ADC, which goes low when there is a new measurement to be read. The other is a 1.024 MHz clock output from a channel of one of the μC timers, which will serve as the master clock for the ADC, determining its sampling rate. In conclusion, 4 pins will be used for this interface.

In the firmware, two callbacks will be used to take care of communications with the ADC:

  • One called for the interrupt launched when the DRDY pin goes low. It will start the reading of the measurements through SPI. It will also read the current state of the context inputs from the DUT, and of the calibration from memory, and place them on a chibiOS mailbox.
  • One called when the SPI transmission ends: it will concatenate the 24-bit measurement bits with the 6 bits received from the previous callback through the mailbox, and send them through another mailbox to the data acquisition thread.

In Conclusion

Taking all the interfaces discussed in this post, we have 44 pins left unassigned.


[AmpeROSE] Automating Calibration

Hello, everyone!

One important design issue we must figure out in order to have a complete schematic of AmpeROSE’s is the automatic calibration mechanism. In this post, I will go over the problem definition, and how we arrived at the two solutions we are considering.

A brief recap

Just as a reminder, the current sensing in AmpeROSE will take place on the shunt resistance: a resistance in series with the current path going from VCC to the device under test (DUT), and then to ground. AmpeROSE will work with four measurement ranges, corresponding to four values of the shunt resistance. In order of decreasing shunt values (or equivalently, increasing max. current value of the range).

  • Rshunt = R4 –> (SW1, SW2 and SW3 open)
  • Rshunt = R4 // R3 –> (SW3 closed, SW1 and SW2 open)
  • Rshunt = R4 // R3 // R2 –> (SW2 and SW3 closed, SW1 open)
  • Rshunt = R4 // R3 // R2 // R1 –> (SW1, SW2 and SW3 closed)

(For more details on the ranges and the principles behind this schema, refer to this previous post. )

Let us call the voltage on the shunt “VFILTRE”, the minimum voltage on the shunt before we switch to a lower range “VOFF”, and the maximum voltage on the shunt before we switch to a higher range “VON”. Under this naming scheme, we want to implement the state machine below, where the state is the states of the switches 1 to 3 concatenated, with 1 meaning “closed” and 0 meaning “open”:


While active, AmpeROSE should manipulate the switches in order to transition between the different measurement ranges, according to this state machine. Failing to do so effectively and spending too much time on a wrong calibration has at least two negative consequences:

  • Loss of measurements, as the reading will simply be stuck on the minimal or maximal value of the range.
  • If we have a relatively large values for current and shunt resistance (for instance, a current that should be measured by the small resistance R1 // R2 // R3 // R4 going through R4), a significant voltage drop will develop over the shunt, probably causing the DUT to brown-out.

We considered several possible implementations for this automatic calibration, which are presented below.

Software-based calibration using the external ADC

An apparently natural solution would to be to control the switches with GPIOs coming from the microncontroller, and using the current measurements from our external ADC to guide the controller in calibrating the circuit. However, we have settled on a sampling frequency of 100KHz for the current, and determined the attributes of our external ADC accordingly, opting for a 24 bit SAR ADC working with this sampling rate.

As 1 / (100KHz) = 10us is more than enough  time for a sudden peak in current consumption to damage the measurement, if the resistance is wrong, using our slow but precise external adc won’t do (considering the reaction times of the power supply circuits for the type of DUT we are targeting, we should aim to reach the correct range, which possibly means going from the highest to the lowest one or vice-versa, within 1 to 3 us).

Software-based calibration using the microcontroller’s internal ADC

A variation of the previous idea would be to use the internal ADC of our microcontroller, set to sample the voltage drop on the shunt at a lower precision, but at a higher rate. This measurement would occur in parallel with the one performed by the external ADC, and would be used exclusively to help the microncontroller determine when to change the measurement range.

Due to logistical reasons, we will be using an STM32F767VI instead of a STM32F407ZG as previously discussed. Both microcontrollers feature internal 12-bit ADCs capable of reaching 2.4 millions of samples per second, which could make it possible to perform the three state transitions needed in the worst case within 2us. Furthermore, they feature an analog watchdog mechanism that may be configured to raise an interrupt when the voltage on one of the ADC channels reaches either a minimal or a maximal limit, which would appear to fit like a glove to the automatic calibration.

The problem in this case is the burden that would be applied on the processor. Having to service up to two interrupts related to the calibration every microssecond, which would be detrimental to its other responsibilities, such as managing communications with the user interface or the sd card.

Hardware-based calibration using comparators and feedback loops

The issues with the two concepts above led us to consider hardware-based implementations of the calibration algorithm. We consulted the schematics of the Power Profile Kit marketed by Nordic Semiconductors, and ascertained that it contains such an implementation. The image below is an adaptation of the Power Profiler Kit calibration circuit to our number of measurement ranges. The original version may be consulted by downloading the “Power Profiler Kit Hardware Files” in the “Downloads” tab of and navigating to the third page of the document “PCA63511_Schematic_And_PCB” inside.


The rectangles in the image are LTC6752 ICs, comparators whose output is HIGH when the input voltage V+ is greater than V- and NOT SHDN is HIGH, LOW when V+ is not greater than V- and NOT SHDN is HIGH, and HIGH-Z when NOT SHDN is LOW. The general idea of this asynchronous sequential circuit is to use the feedback on the AND gates to store the state of the calibration state machine, and transition according to the comparators.

Analysing this circuit was fruitful, particularly in terms showing how the LTC6752 could be used, but an options with less components, and simpler to analyse in terms of timing would be preferable, in order to reduce the complexity of the physical implementation on the PCB.

Hardware-based calibration using RS-latches

An alternative with such desirable characteristics would be to use RS-latches to store state, and use only two comparators, such as in the circuit below:


Hardware-based calibration using a bidirectional shift-register

This last option uses a standard component of the 74xx family of digital logic components to implement the calibration state machine.

The functional diagram of the 74HC194 is shown below (source: Its output “Q0 Q1 Q2 Q3” is set asynchronously to 0 when MR is low. Otherwise, it may change at every rising edge of the clock CP, depending on the state of the control inputs S0 and S1:

  • When S0 == 0 and S1 == 0, the output doesn’t change: “Q0(n+1) Q1(n+1) Q2(n+1) Q3(n+1) ” = “Q0(n) Q1(n) Q2(n) Q3(n) ”
  • When S0 == 1 and S1 == 0, the output becomes the result of appending DSR to the left of the original output and taking the leftmost 4 bits: “Q0(n+1) Q1(n+1) Q2(n+1) Q3(n+1) ” = “DSR Q0(n) Q1(n) Q2(n) ”
  • When S0 == 0 and S1 == 1, the output becomes the result of appending DSL to the right of the original output and taking the rightmost 4 bits: “Q0(n+1) Q1(n+1) Q2(n+1) Q3(n+1) ” = “Q1(n) Q2(n) Q3(n) DSL”
  • When S0 == 1 and S1 == 1, the output receives the parallel input: “D0 D1 D2 D3”: “Q0(n+1) Q1(n+1) Q2(n+1) Q3(n+1) ” = “D0(n) D1(n) D2(n) D3(n)

Let us consider what happens when DSL is fixed at HIGH, and DSR at LOW, and S0 and S1 can never be high at the same time. The following state machine is then implemented, with the state written as “Q0 Q1 Q2 Q3”.

We may observe that the state machine within the dotted rectangle is the same one we want to implement for the calibration, it’s just necessary to make the equivalencies:

  • Q3 = switch for R3;
  • Q2 = switch for R2;
  • Q1 = switch for R1;
  • S0 = VFILTRE < VOFF (output of a comparator)
  • S1 = VFILTRE > VON (output of a comparator)

Below, a first version of the connections. A “safe” value is fixed on the parallel input for the case where S0 and S1 are high at the same time, which is not expected to happenn during normal operation of the circuit.

The additional state “1111” has the same effect as “0111”, and can only be reached from it when the comparator indicates VFILTRE > VON, so it shouldn’t be dangerous per se. It does imply, however, that going from “all the switches on” to “all the switches off” may take up to 4 clock cycles. Two possible solutions are to change the equation of S1 to “(VFILTRE > VON) AND NOT Q1”, which requires adding more logic, or to clock the shift register at more than 4MHz.


During initial calibration, the processor must be able to control the switches. directly. If we have GPIO to spare, the following connection gives the processor power to bypass the automatic calibration when necessary and assign whatever values it needs to to the register outputs through the parallel input (it adds two OR gates, though). During normal operation it could set the GPIOs 2 to 5 to the “safe” value.



The two last ideas discussed seem to be the most interesting options at this moment: one is a simplified version of a design implemented by a working product, and other would require very few components. We intend to perform SPICE simulations of versions of our measurement circuit incorporating both options, in order to validate them and decide on our final design.

[AmpeROSE] Continuous ∫ntegration

Hello, everyone!

Besides looking into the measurement circuit, one of our tasks for this week, was to establish our plan for continuous integration. The continuous integration routine performed on each commit made to our depot should verify if the contributed code complies with our style guidelines, compiles correctly and passes any tests that have been defined.

A necessary first step in this process was to determine what languages will be part of the Amperose project. We decided to use C for the firmware that is executed on our device, and python for the user interface program that will communicate with AmpeROSE through ethernet. With this in mind, we proceeded to define how our code will be evaluated by our continuous integration routine:

Style verification: we’ll use clang-format to verify the style of C code, based on a configuration file we have defined (a slightly modified version of the Webkit standard). For python, we’ll follow the PEP-8 standard (, and use the pep-8 utility ( to verify code style.

Compilation: C code will be compiled with the arm-none-eabi-gcc toolchain. Python code will be interpreted with python3.

Tests: We will use unittest for Python unit testing, and Criterion ( for C.

In conclusion the sequence followed by our continuous integration routine will be: install the dependencies of the python program using pep3 –> check the style of python and C code –> compile C code –> run tests. We’re about to start working in earnest with our development board and with pyqt to implement the firmware and the user interface, so having this routine in place will be very useful in ensuring the quality of our code.

[AmpeROSE] Choosing AmpeROSE’s Brains

Hello, everyone!

As the time to start building AmpeROSE draws near, we chose the components for its digital part, including a very crucial one, the: microcontroller. We had some aspects in mind to direct us in choosing it:

  • It should have all the communication interfaces our architecture demands: 10/100 Ethernet, SPI and SDIO for the SD card, and USB.
  • It should preferably be an ARM-based processor of the STM32 line, to take advantage of the familiarity with developed with them and the arm-none-eabi toolchain over these past few months, as part of our courses.
  • It should meet our estimations for operations per second. These are not too constraining, as our sampling frequency is a relatively low 100KHz. For the main task of reading the different bits that compose a measurement (the output from the analog-to-digital converter, the GPIO from the device under test, the two bits describing the current calibration) and concatenating them into a 32-bit measurement word, we estimate 800 000 operations per second, including memory accesses, bitwise-or operations and shifts.

In the interest of building an affordable device, we looked at the two most basic processor families that met these requirements: the STM32F207 and the STM32F407. Searching through our component suppliers, it turned out favourite STM32F407 microcontroller, the STM32F407ZGT6, is available for just under three euros more than any available STM32F207 we could find.

Considering this small difference in price, we lean towards using the STM32F407ZGT6 to build our AmpeROSE prototype, as we have already worked with a development board containing them, which could be used to test some of our code. Furthermore, using this more capable processor ensures us some room should it turn out we underestimated the magnitude of the calculations needed, or to add more firmware functionalities further along in the project.

AmperROSE Week 3: Architecting AmpeROSE

Hello, everyone!

In this third week of the project, while part of the team focused on researching ways to measure small currents precisely, the rest (Michel, Bilal and me) focused on defining the overall architecture for the digital part of the device, in particular the method used to communicate with the user interface. This is a post explaining our results in this front:

A general view

Our project is divided in two parts:

  • An analog part responsible for the measuring the current being drawn by the Device Under Test (DUT)
  • A digital part responsible for

The interface between the two parts will be, naturally, an Analog-to-Digital Converter (ADC). Here is a general view of the architecture for the digital part of AmpeROSE, in image form:

Below is a couple of comments on the role that some of these components will play in AmpeROSE’s operation:

SD card

We envision two modes of operation for AmpeROSE:

Online mode

In this mode, AmpeROSE is directly connected to a third party (where the user interface program is running) through Ethernet. In this mode, the measurements will be streamed directly to the user interface as they are collected.

Offline mode

Alternately, it will be possible to use AmpeROSE without a connection . In this mode, the measurements will be stored in a SD card, from which they may be recovered later.


AmpeROSE is intended as a tool to aid in the profiling and optimization of the energy consumption of iot devices. Thus, it should provide a way to associate meaningful information about the state of the computation with the current measurements.

The solution we have adopted is to add six input pins to AmpeROSE, to which GPIO pins from the DUT may be connected. The user user will then be able to instrument the code running on the DUT to change the state of said GPIO pins in order to reflect the state of the program. For instance, a pin could be toggled depending on whether the device’s WiFi module is on of off.  These inputs will be sampled at the same rate as the current, and their will be associated with the corresponding current measurement when it’s streamed the user interface or saved in the sd card.


Three measurement ranges will be provided by AmpeROSE:

  • 1 nA      –   1 uA
  • 1 uA      –   1 mA
  • 1 mA     –   1A

One of the main jobs of the processor will be to automatically calibrate the measurement stage to the adequate range as the current being drawn from the battery changes. For the moment, a preliminary calculation indicates that we will not need more than 24 bits (a more detailed calculation is planned very soon). Therefore, we plan to use a 24 bit ADC. Each measurement will then be a 32 bit word consisting of: 24 bits of measurement + 2 bits to indicate the range + 6 bits with the sampled states of the 6 inputs from the DUT.


USB2.0 is a widespread interface supported by a multitude of systems,  from computers to embedded devices. Theoretically, it can transfer data up to 60MB/s. However, due to bus access constraints, the effective throughput of the High Speed signaling rate is limited to 35 MB/s.

Transferring a word at 10 MHZ would give a maximum rate of 32 * 1000000 = 40MB per second > 35 MB/s, therefore, USB2.0 is not well suited for our purpose.

Of course, we could choose USB3.0 that provides an effective data signaling rate of 400 MB/s, however, it is not supported by all devices, and the use of it would add strong constraints in order to use AmpeRose as a precision device to measure low current.

In conclusion, USB will only be used as power supply to charge the battery.

Fast Ethernet

Fast Ethernet is a standard network interface also supported by many systems. It can transmit data up to 100MB/s, so it supports our maximum throughput of 40MB/s at 10 MHZ. In addition, it supports full duplex mode, which means that, while transmitting data to the third party, AmpeROSE will be able to receive commands from it.

AmpeROSE Week 2: The First Presentation

Hello, everyone!

Here is an update for the AmpeROSE project:

The First Presentation

For this week, our main mission was to prepare an initial presentation of our project to be done before our teachers and colleagues. The presentation had to cover five essential aspects:

  • What is our goal with this project, and what are the use cases we envision for it?
  • What are the main features of the project?
  • What are the the technical limitations our project will suffer from?
  • What are our Project Specific Success Criteria (PSSC)? These are a series of simple “yes or no” (or “done or not done”) questions, each corresponding to a step in the design and construction of the AmpeROSE device, such that a step will only be considered complete if  the corresponding PSSC may be answered affirmatively.
  • Which technologies will be used for data communication in the project?

Thinking about these questions really helped make the AmpeROSE device more concrete to us. Here are the answers we have at this point, to a lesser or greater degree, they are all likely to evolve as the project goes on:


Our goal with ampeROSE is to build a prototype for an affordable digital ammeter that integrates naturally with the conception of low-power connected objects. The ammeter will be placed between the battery and the device under test, and transmit the measurement data to a computer, where an user interface makes it possible to visualize the data and treat it (for instance, with some of the usual options found in a digital oscilloscope: FFT, integration, trigger options, determinations of min and max values…).

Main Features

The main features are similar to what was described in the previous post about AmpeROSE:

  • High sampling rate (at least 1MHz).
  • A dynamic range going from 10nA to 100mA.
  • Self-calibration.
  • Data transfer to a host pc.
  • A simple and effective user interface.

Technical Limitations

An important technical limitation is that the measurements with AmpeROSE will necessarily be intrusive to some degree to the normal operation of the device under test. Our challenge is then to diminish this intrusiveness as much as possible, so the measurements are as accurate to the real values as possible.


We structured our PSSC around five main themes:

  • Current Measurement: the design and implementation of the analog circuitry used to measure the current being drawn from the battery by the device under test, and how it will interface with the digital part of AmpeROSE.
  • Data Processing: the design and implementation of the digital part of AmpeROSE (selelection of the embedded processor, development of the firmware…)
  • Circuit Board: The design and implementation of the circuit board which will house both the digital and analogic composants of AmpeROSE.
  • Packaging: The conception of the 3d-printed packaging that will house the circuit board.
  • User Interface: The development of the program that communicates with AmpeROSE, through which the user will be able to access the data collected by the ammeter.

Communication Technologies

We are still considering USB 2, USB 3 and Ethernet as options for connecting AmpeROSE to the computer hosting the user interface (or even having two or three of technologies as options to the user). A question that must be answered before we can reach a decision is whether the bit rate that will be required for transmitting the measurements to the user interface is compatible with even USB 2. Some back-of-the-envelope calculations suggest it should be, but we really need to determine this more formally, which leads us to:

Numbers, numbers, numbers…

For this new week, the first goal (indeed, to be completed by the end of monday morning) is to augment our description of our project with informed estimations of all the key quantities related to it:

  • What computing power will be demanded from the embedded processor within AmpeROSE (multiplication / additions per second…)
  • How much measurement data AmpeROSE should able to store internally at any given time.
  • What bit rate will be required for the communication between the AmpeROSE device and the computer hosting the user interface (as mentioned)

And most important of all:

  • etc.

This exercice will be essential in order to proceed to the selection of specific components for AmpeROSE. Check in next week to learn what conclusions we reached!

ampeROSE – Hello, World!

Hello, everyone!

We are the team ampeROSE, and over the next 100 days we will design and build an ammeter adapted to the task of profiling the energy consumption of Internet of Things (IOT) devices. Our goal is to arrive at a prototype for a device that is as affordable as possible, all while meeting the particular needs of engineering teams working in the IOT space. Some of such needs that we are already aware of are as follows:

The current consumption of an IOT device may be kept in the range tens of nanoamperes while in sleep mode. On the other hand, such a device will hit peaks of 20 mA when it’s transferring data through technologies like BLE and Lora, and 100 mA when it’s using Wi-Fi. Thus, the ammeter must have a dynamic range large enough to cover this variation of magnitude in the order of tens of millions, so that both extremes may be precisely profiled. Being able to effectively take the peaks in current consumption into account is important, because the performance of batteries used in the context of IOT decreases dramatically outside of the behavior for which their capacity is specified (usually an average current consumption of 1uA with peaks of 2mA).

Furthermore, in order to keep track of these sudden variations in current consumption, the ammeter must be able to auto-calibrate, and achieve a sampling rate of 1 MHz or more. This elevated sampling rate, in turn, will make it necessary to find good solutions for storing large amounts of measurements in memories integrated in our device, and for transfering them to a host computer (with USB2, USB3 and/or Ethernet).

Finally, the ammeter should have an associated UI that is simple and effective, and have features that facilitate its integration with automated testing, such as being able to be started through either software or an external input.

We are looking forward to facing the design challenges that building the ampeROSE device will present, and to sharing them with you in this blog!