Using an Arduino Due as a mini-QC controller

My Nissan Leaf Forum

Help Support My Nissan Leaf Forum:

This site may earn a commission from merchant affiliate links, including eBay, Amazon, and others.
While trying to QC, the car can get offended enough to refuse to charge on L1/L2.
It can also refuse to charge on QC, which is more understandable.

With the Android LEAF Battery app's new ability to read DTC (Diagnostic Trouble
Codes), and the future feature of being able to reset some of the codes (which
should only be used very sparingly), we will more often, I suspect, be able to
"rescue" an offended LEAF, rather than require a trip, or tow, to a dealer. :D

Some working Sketches will be helpful.
More later.
 
Due CAN Logging Project:

1. Get two CAN transceivers (3.3v preferred), wire to the Due's two
CAN ports (A and B), and make a 4-inch CAN-bus between the two.

2. Configure as a 500000 baud CAN bus, and send a message each 100
milliseconds on A and receive on B. Use 11-bit MsgID format, with
8 data bytes, ID hex 801. The first two bytes of data as a counter
that is incremented with each message sent, and the remaining bytes
sent as 0xFF (as an unused bytes filler).

3. Use a Timer to send the messages, and a polling loop to receive them.
Blink the LED (on D13) when the message arrives.

4. Check that the expected data is there, and report number received
and the number of errors to the IDE Serial Monitor (using Serial.print
and.println which use the Programming USB connection).
Report once a second. Use baud rate 115200.

5. Write each Message as hex (4 characters for data length (0 to 8) and
the MsgID (like 8701) and then the 8 data bytes, each as a space and
two hex characters, then, an end of line.
Increase the sending rate to 1000 per second.

6. At some point the polling loop will probably "lose" some messages,
so change the message receiving to a message received handler
(interrupt routine), checking quickly for data-sequence errors.
Continue to report the statistics to the Serial Monitor.

7. As messages are received, write them to a 512-message circular buffer,
and try to keep the buffer from overflowing by taking the messages, one by one
out of the buffer (in the main loop) and writing the message to
the Serial Monitor.

8. Change to sending the log output in binary format, via the
Native USB Port, to CAN-Do. (this step added)

9. At each message-send timer interrupt, send 2 messages,
then 3, and 4, and 5, as "bursts" of messages. Observe the limits
of this logging process.

------------
Further extensions:
1. Add a second and millisecond time stamp as each messages is received.

2. Synchronize the time stamp with the RTC, for 0 ms at the start of each second of the RTC.
Synchronize the 0-second with the start of the RTC minute.

3. Format the logging data in binary, as the CAN-Do ".akc" format (14 bytes per message),
and receive the data with CAN-Do, and plot the first and second data bytes.

4. Add a Date-Time pseudo-message (MsgID FFF) to the received-message buffer
just before the first received message after the start of each minute.
Do not worry about setting the RTC for now - the Due has problems with
maintaining the current date and time on the internal RTC.

5. Handle (avoid) overflow of the circular message-receive buffer
by tossing out the message that would cause the overflow, AND
overwriting the MsgID and data of the last message in the buffer,
to indicate that messages were lost here, using the first two bytes
as the lost-message count. Keep a flag that says that the buffer is
in the "overflowed" state. Done correctly, this can be fast, and indicate
exactly where any received messages were lost.

more later
 
I should be getting my "234" and "235" TI transceivers from Mouser today.

I got some Due proto boards from Florida a few days ago.

I bought 7, 5, 4-inch color touch displays from CTE (ColdTears
Electronics) and I just got some demo sketches working on
some of them.
 
Just ordered these Ti SN65HVD251D from DigiKey.

I assume you can write to one and read from the other for testing purposes...So you want to stick with the Due?
 
Stick with the Due for now, but... who knows what we will discover.
Hopefully it will work well, though we might have to avoid using some
libraries.

Other Due-sketch projects:

1. Reading A-to-D, perhaps 6 or more inputs, about once per
milli-second, reliably, and cleanly.
Protect the inputs perhaps with zeners.
Probably use a Timer-interrupt to do the reading,
and read the results as quickly as one can.

Measure the microseconds used to do the read,
and store the data in global variables, and report to
the Serial Monitor each second.

Read the Due board's 5V voltage and the board's VIN voltage.
Then, read the 120v power input voltage (caution), and current
to a lamp or something similar.

Send some CAN messages to report the findings, and use the
logged data to investigate and plot the lamp's inrush current,
both when the lamp is cold, and hot.

2. Add the setting and reading of digital values,
which should be very fast.
Measure how fast, either in CPU clock tics, or in microseconds.
If one is too fast to measure, measure 100,or 10000 or so.

Ground a line that might be externally pulled up to 12v or more.
Connect a line to 12v or so.
Protect the Due's inputs and outputs.

Send more CAN messages to log the digital data.
and plot the bits with CAN-Do, like a logic analyzer.

3. Set the Pulse Width modulation of a 14 kHz output to
update the duty cycle (modulation) at 1ms intervals,
initially as a triangle wave, for testing.

Period of about 6000 clock (84 MHz clock), and modulate from
1000 to 5000 to make a 120 Hz triangle wave.

Log the modulations as CAN data, and graph with CAN-Do.
 
Due Projects, continued.

Correction:
The Due PWM gives us more usable precision than the PWM
in the AVR-CAN, not due to the counter register length (or
so I have been informed), but just due to the fact that the
CPU clock is almost 6 times faster in the DUE.
Thus, with a 14 kHz period PWM output, we get 6000 clock
counts in the Due, but we had only about 1024 in the
AVR-CAN, just because of the slower CPU clock.

----------
Goals of the Due Programming Projects:

1.Control the power supply to regulate its output voltage
and current (usually only one at a time). Thus takes
adjustment and experimenting with each unique set
of hardware. However, the main control functions
are similar for most systems: achieve very reliable Safety,
and maintain satisfactory control.

2. Use the PC and the Due's Programming Port to monitor
the control and charging process in real time, and
adjust parameters as needed for experimentation.

3. Use the Native USB port to the PC for detailed
logging of all the QC CAN messages, and the power
supply's operational data, for later analysis,
particularly of the fast occurring processes that
are essentially impossible to observe manually.
Use CAN-Do to capture, log, and graph the data.

4. Use at least one, perhaps many PWM outputs
as the primary control of the power supply
regulation, usually controlling one or more
high voltage, high current switches in the
power supply.

5. When not attached to a PC, optionally use
the Native USB Port in host mode to write the
log data to a file on an SD chip, or micro-SD chip,
or perhaps even a fast flash drive.

6. Support a local display and at least Start and
Stop buttons on the "face" of the mini-QC device.

7. Design and integrate an Emergency-Off system.

8. Package and provide for adequate cooling,
handling fault conditions, like over-temperature,
safely, reliably, and quickly.

9. Oh yes, and charge the various LEAF versions
reliably, safely, and dependably. :D


----------
Modify the CAN Project described earlier:

Send the Log data to the PC via the Native USB Port,
not the Programming USB Port.

----------
Additional Projects:

1. Reliable use of the Native USB Port to send data out to the PC.
Others have observed very infrequent unexplained loss of data.
Investigate and find a fix, maybe not sending using the Due library,
which normally uses SerialUSB.print.

2. Send 14 byte binary pseudo-CAN Messages to CAN-Do via the
Native USB port, and achieve error-free transmission at
at least 115200 baud, sending at least 5000 messages per second.

3. Support logging to a USB memory device, using the Native
USB Port in Host mide. Write CAN-Do compatible files.

4. Support a local display on the mini-QC, type yet to be
determined. I am investigating the ColdTears Electronics
color touch TFT displays, with sizes from 3.2 inches, 3.5, 4,
5, and 7 inches. The smaller are 480x320, and the two larger
are 800x480. CTE also has a display shield for these displays.
 
In the last several posts, I have suggested a number of
projects that need programming and testing on the Due.

We have done essentially all of these on the AVR-CAN,
and a few on the Mbed, but the Due is new territory.

However, having done it once, the goals are clearer,
and I am hoping that the individual sub-parts can
be included in test Sketches as mostly subroutines,
so that the parts can be more easily integrated into
a growing whole.

Perhaps we can build a flowchart of the overall
process, but the end results will need to be
very hardware specific.

Often, speed, buffering, and handling interrupts
are critical to handling a real-time process reliably.

The Due Arduino Core (sort of an Operating System)
might not give us sufficiently responsive (or even
reliable control, so we might have to find a way around
the Core, to handle the interrupts ourself.

Sadly, there seems to be a lot of unknowns with
the Due, and the Datasheet for the main uP is
1467 pages long, with the Table of Contents
at the end!

If my suggested goals or projects do not
seem appropriate, please feel free to make
constructive suggestions or corrections.

It is not hard, but there are lots of details.
I suggest trying to use the growing number
of Arduino libraries, but it is not always a
simple task to determine if they work on
the Due, or even Compile without errors.

When Arduino changed the IDE from
1.5.2 to 1.5.3 (both Beta versions), some
applications no longer compiled.

Google
Arduino Due Forum
and read some of the 1000 threads.
Lots of discoveries being made.

Cherrs, Gary
 
Arduino IDE version 1.5.4 r2 (still Beta) is released at
http://arduino.cc/en/main/software" onclick="window.open(this.href);return false;

The Arduino Due Forum is at
http://forum.arduino.cc/index.php?board=87.0" onclick="window.open(this.href);return false;

Cheers, Gary
 
garygid said:
Due Projects, continued.

Correction:
The Due PWM gives us more usable precision than the PWM
in the AVR-CAN, not due to the counter register length (or
so I have been informed), but just due to the fact that the
CPU clock is almost 6 times faster in the DUE.
Thus, with a 14 kHz period PWM output, we get 6000 clock
counts in the Due, but we had only about 1024 in the
AVR-CAN, just because of the slower CPU clock.

----------
Goals of the Due Programming Projects:

1.Control the power supply to regulate its output voltage
and current (usually only one at a time). Thus takes
adjustment and experimenting with each unique set
of hardware. However, the main control functions
are similar for most systems: achieve very reliable Safety,
and maintain satisfactory control.

2. Use the PC and the Due's Programming Port to monitor
the control and charging process in real time, and
adjust parameters as needed for experimentation.

3. Use the Native USB port to the PC for detailed
logging of all the QC CAN messages, and the power
supply's operational data, for later analysis,
particularly of the fast occurring processes that
are essentially impossible to observe manually.
Use CAN-Do to capture, log, and graph the data.

4. Use at least one, perhaps many PWM outputs
as the primary control of the power supply
regulation, usually controlling one or more
high voltage, high current switches in the
power supply.

5. When not attached to a PC, optionally use
the Native USB Port in host mode to write the
log data to a file on an SD chip, or micro-SD chip,
or perhaps even a fast flash drive.

6. Support a local display and at least Start and
Stop buttons on the "face" of the mini-QC device.

7. Design and integrate an Emergency-Off system.

8. Package and provide for adequate cooling,
handling fault conditions, like over-temperature,
safely, reliably, and quickly.

9. Oh yes, and charge the various LEAF versions
reliably, safely, and dependably. :D


----------
Modify the CAN Project described earlier:

Send the Log data to the PC via the Native USB Port,
not the Programming USB Port.

----------
Additional Projects:

1. Reliable use of the Native USB Port to send data out to the PC.
Others have observed very infrequent unexplained loss of data.
Investigate and find a fix, maybe not sending using the Due library,
which normally uses SerialUSB.print.

2. Send 14 byte binary pseudo-CAN Messages to CAN-Do via the
Native USB port, and achieve error-free transmission at
at least 115200 baud, sending at least 5000 messages per second.

3. Support logging to a USB memory device, using the Native
USB Port in Host mide. Write CAN-Do compatible files.

4. Support a local display on the mini-QC, type yet to be
determined. I am investigating the ColdTears Electronics
color touch TFT displays, with sizes from 3.2 inches, 3.5, 4,
5, and 7 inches. The smaller are 480x320, and the two larger
are 800x480. CTE also has a display shield for these displays.


Ok, I will play with the AD while waiting for my CAN-transceivers. How many PWM outputs do we need? Will they all be the same frequency?
 
garygid said:
1. Reading A-to-D, perhaps 6 or more inputs, about once per
milli-second, reliably, and cleanly.
Protect the inputs perhaps with zeners.
Probably use a Timer-interrupt to do the reading,
and read the results as quickly as one can.

Measure the microseconds used to do the read,
and store the data in global variables, and report to
the Serial Monitor each second.

Read the Due board's 5V voltage and the board's VIN voltage.
Then, read the 120v power input voltage (caution), and current
to a lamp or something similar.

Naively one would assume that the AD inputs are high impedance so the 3.3 V limit would not apply.
But to quote from the Due webpage http://arduino.cc/en/Main/arduinoBoardDue" onclick="window.open(this.href);return false;:

Analog Inputs: pins from A0 to A11
The Due has 12 analog inputs, each of which can provide 12 bits of resolution (i.e. 4096 different values). By default, the resolution of the readings is set at 10 bits, for compatibility with other Arduino boards. It is possible to change the resolution of the ADC with analogReadResolution(). The Due’s analog inputs pins measure from ground to a maximum value of 3.3V. Applying more then 3.3V on the Due’s pins will damage the SAM3X chip. The analogReference() function is ignored on the Due.

Not sure if this applies to the analog pins, but just in case, a voltage divider should be used.

Reading 120 V input voltage and current:

I do this on the two legs of my main breaker, but this is all through inductive, isolated measurements, i.e.
CT coils for the current and AC transformer for the voltage.

There I pull the AC up to 2.5 V reference, the same would be needed here (that is 1.65 V ref for the due). Note that this works, because current and voltage measurements are isolated.

Also the current measurement may require some amplification (or maybe not since we a 12 bit ADC on 3.3 V rather than a 10 bit ADC on 5 V).

For the QC application, do you want to measure AC voltage/current anywhere?
Or will this be on the DC side?
For AC, some extra analog circuitry would be required.

If we only measure on the DC side (and have isolation), a voltage divider/shunt for voltage/current would work.
Maybe I will try this with 12 V DC from a PC power supply....I have 60 Watt 12v bulb as load, so that should work for demonstration purposes.
 
Here we go, reading from 6 ADC at 12 bits and reporting the time it spent on AD conversion. Note that the output time is for acquiring 1000 samples. Its in us.
Takes 25 us for 6 conversions with the register hack (see below). Takes 10 times longer without. Amazing!

Credit goes to this guy:

http://www.djerickson.com/arduino/" onclick="window.open(this.href);return false;

Very useful read.


Code:
#include <DueTimer.h>


unsigned long delta_t=0;
int n=0;

void AD_Handler()
{
  unsigned long t1=micros();
  word val0=analogRead(A0);
  word val1=analogRead(A1);
  word val2=analogRead(A2);
  word val3=analogRead(A3);
  word val4=analogRead(A4);
  word val5=analogRead(A5);

  delta_t+=micros()-t1; // benchmark
  n++;
  if(n>999)
  {
    Serial.println(delta_t,DEC);
    n=0;
    delta_t=0;
  }
}

void setup(){
        Serial.begin(115200);
        REG_ADC_MR = (REG_ADC_MR & 0xFFF0FFFF) | 0x00020000; //makes the ADC run fast
	Timer3.attachInterrupt(AD_Handler);
	Timer3.start(1000); // Calls every  1 ms
        analogReadResolution(12); // set to 12 bits
}

void loop()
{
  
}
 
Reading ADC values at 1 kHZ and sending them to SerialUSB works.

The only thing I havent quite figured out is this:

In order to measure any voltage, i have to attach the ground of my test voltage to the arduino ground. If the Arduino is connected via USB to the PC, the arduino ground is the PC ground, correct? Which should be mains ground, since the PC is not isolated.

If I e.g. use another ATX to e.g. power up a lamp at 12 V, its ground should be tied to mains ground as well and thus the Arduino and the other ATX should have the same ground. So no need to connect them, right?
But apparently this is not working...Is the arduino ground floating? Or the other ATX?

Code:
#define BUFFER_SIZE 1000

#include <DueTimer.h>


unsigned long delta_t=0;
int n=0;
uint16_t b0[BUFFER_SIZE];
uint16_t b1[BUFFER_SIZE];

void AD_Handler()
{
  //unsigned long t1=micros();
  while((ADC->ADC_ISR & 0x80)==0);
  while((ADC->ADC_ISR & 0x80)==0);// wait for two conversions          
  b0[n]=ADC->ADC_CDR[7];// read data on A0 pin
  b1[n]=ADC->ADC_CDR[6];// read data on A1 pin

  //delta_t+=micros()-t1; // benchmark
  n++;
  if(n>BUFFER_SIZE-1)
  {
    SerialUSB.write((uint8_t *)b0,2*BUFFER_SIZE);
    SerialUSB.write((uint8_t *)b1,2*BUFFER_SIZE);

    n=0;
    delta_t=0;
  }
}

void setup(){
  SerialUSB.begin(115200);
  //REG_ADC_MR = (REG_ADC_MR & 0xFFF0FFFF) | 0x00020000; //makes the ADC run fast
  Timer3.attachInterrupt(AD_Handler);
  Timer3.start(1000); // Calls every  1 ms
  analogReadResolution(12); // set to 12 bits
  int t=analogRead(0);
  ADC->ADC_MR |= 0x80; // these lines set free running mode on adc 7 and adc 6 (pin A0 and A1 - see Due Pinout Diagram thread)
  ADC->ADC_CR=2;
  ADC->ADC_CHER=0xC0; // this is (1<<7) | (1<<6) for adc 7 and adc 6
}

void loop()
{

}
 
With a typical isolated power supply, the earth ground will be
the ground for the power supply chassis, the Due controller,
and (when connected) the car.

So, some connections to the Power Supply will need to be
opto-isolated, like the driver to the High Voltage switch (often an IGBT).

Yes, we would like to measure the AC Input voltage and current,
and the floating High Voltage of each power supply, along with the
Output current. And a few other things, like internal temperature(s).
 
If you want to do this for 10 units, we need to multiplex some of the ADCs. Looks like we can get a single reading in ~ 4 us, so at a 1 kHz sampling rate, you could read from 250 sensors (with multiplexing).
 
Reading from the ADC while being connected to a PC is not the optimal way...its incredibly noisy. Plus it adds the additional problem of having the ground of the Arduino not floating...

So next project will be to redirect the output from serialUSB to an SD card...or getting the data off by other means than the USB cable...
 
got my CAN transceivers.
The DUE examples all seem to work. I am not familiar with the CAN protocol, so would like to learn a bit more. Any suggestions for basic reading?
 
Short CAN intro:

Send messages with 0 to 8 bytes of data, along with the
message ID (000 hex through 799 hex, or 11 bits) and
a count of the data bytes to be included (0 through 8).
I use some of the Fxx MsgIDs for pseudo-messages,
which are not transmitted on the CAN bus.

So, think of it as N MID D1 D2 D3 D4 D5 D6 D7 D8, which
I usually store in 10 bytes as ID NM D1... D8 where
I set/force the "unused" data bytes to 0xFF.

When receiving messages, I usually store two more
bytes for a (Seconds*1024 + milliseconds) Time Stamp,
with each message, using SS MM for notation.

If I an logging from two sources, I add another byte
for Origin (RR), with EV-CAN bus = 1, CAR-CAN = 2,
AV-CAN = 3, and QC-CAN = 4. I use zero (0) for
Date-Time messages, text messages, and other
pseudo-messages that apply to any(all) channel(s).

I add a check-byte (BB), for a total of 14 bytes for the
Multi-CAN file format, or 13 bytes for the individual
CAN Log files.

So, a Single-CAN (.evc, .can, .avc, or .qcc) file has fixed length
records, as BB ID NM D1... D8 SS MM ... (as I recall), 13 bytes each.

Then, the Multi-CAN (.alc) file also has fixed length records,
as BB ID NM D1... D8 SS MM RR ... (as I recall), 14 bytes each.

Look at some of the log files I have online with
a HexEdit program, and then with CAN-Do... at
http://www.wwwsite.com/puzzles/cando/" onclick="window.open(this.href);return false;
 
For sending and receiving quickly, with low
overhead (sort of in the "background", one
usually needs to use hardware that includes a buffer,
or send and receive interrupts.

When the hardware receive buffer is full, quickly interrupt
and empty the receive buffer into a larger software
buffer.

When the hardware transmit buffer is empty, and there
is more to send, get an interrupt which quickly "fills" the
hardware transmit buffer.

For the Due, see the work here:
http://forum.arduino.cc/index.php?topic=186388.0" onclick="window.open(this.href);return false;
 
I got the Coldtear Electronics (CTE) 3.2 inch display's touch
surface working, with the UTouch library, doing the needed
calibration, and using the CTE display shield for the Due.
It is the CTE32HR, at 480 x 320 resolution.

I have screens up to 7 inches that work on the same shield,
but I will have to calibrate for them and add display selection
into the initialization of the library, similar to how the UTFT
library supports a lot of different displays.

However, for now, I am trying to make the smaller display
work as a suitable User Interface for controlling the
mini-QC, monitoring parameter values, and accepting
user inputs.

Later, after things are working, I might move to the
larger 4-inch CTE40 display.

I am working on displaying values, and changing parameters
with touch input, possibly eliminating the PC (assuming
we get logging to USB SD or Flash working fast enough.

Actually, for logging the mini-QC only, handling a few hundred
messages per second should be enough, unless in debug
mode, where we might want to add logging a couple thousand
pseudo-messages per second.
 
garygid said:
For sending and receiving quickly, with low
overhead (sort of in the "background", one
usually needs to use hardware that includes a buffer,
or send and receive interrupts.

When the hardware receive buffer is full, quickly interrupt
and empty the receive buffer into a larger software
buffer.

When the hardware transmit buffer is empty, and there
is more to send, get an interrupt which quickly "fills" the
hardware transmit buffer.

For the Due, see the work here:
http://forum.arduino.cc/index.php?topic=186388.0" onclick="window.open(this.href);return false;

Are you talking about sending of CAN messages or serial port messages?

To get a sense of the workload for the DUE, what needs to be run ?

So far we have:

- Every millisecond, read N sensors (or maybe just the critical values at this rate. Which readings are time critical???)

- Every millisecond, read/send a CAN message. Or do we respond to CAN messages when they arrive? It seems like the CAN bus on the Arduino can wait for messages. I havent gotten much into it yet, but presumably there is an interrupt to which we can attach a CAN message handler? How much CAN messages does the QC CAN send per second?


- Every millisecond (?) set some PWM output on X(?) pins, based on inputs (analog sensors, CAN, user interface)

- Every second(?) log/transmit data from buffers (analog/CAN) elsewhere
 
Back
Top