Arduino and AD7410 I²C temp sensor

On request, the source code of using the Analog Devices AD7410 I²C temp sensor. (Datasheet: adt7410)

#include <Wire.h>

//ADT7410 13/16-bit digital temperature sensor
//RED (VDD): 2.7 ... 5.5V
//BROWN (GND): 0V
//Arduino uno, wires:
//PURPLE 1 (SCL): SCL (near AREF, should be equal to ANALOG5)
//PURPLE 2 (SDA): SDA (near AREF, should be equal to ANALOG4)
//Arduino due, wires:
//PURPLE 1 (SCL): SCL (pin 21)
//PURPLE 2 (SDA): SDA = (pin 20)
//Arduino IDE 1.5 compatible

#define ADT7410_I2C_ADDRESS 0x48
#define tempRegister 0x00
#define configRegister 0x03
#define selectCode16bitMode 0x80


void setup() {
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600); // serial connection
  set16bitMode();
}




void loop() {
  delay(5000);
  serieelPrint(); //print on serial port
}


//set ADT7410 in 16-bit temp value mode
void set16bitMode() 
{
  Serial.println("Setting 16-bit mode...");
  Wire.beginTransmission(ADT7410_I2C_ADDRESS);
  Wire.write(configRegister);
  Wire.write(selectCode16bitMode);
}



//gives back the temperature value
float readTemp()
{
  //set read register
  Wire.beginTransmission(ADT7410_I2C_ADDRESS);
  Wire.write(tempRegister);
  Wire.endTransmission();
  //receive data
  Wire.requestFrom(ADT7410_I2C_ADDRESS, 2);
  byte MSB = Wire.read();
  byte LSB = Wire.read();
  
  //check for positive or negative sign
  boolean sign;
  if(MSB>0xA0) {
    sign=0; //negative
  } else {
    sign=1; //positive
  }
  
  //concat MSB&LSB
  float tempValue = MSB * 256;
  tempValue+=LSB;
  
  //BIN to DEC
  if(!(sign)){
    tempValue-=65536;
  }
  tempValue/=128;
  
  return tempValue;
}

void serieelPrint()
{
  Serial.print("Unit: ");
  Serial.print(ADT7410_I2C_ADDRESS, HEX);
  Serial.print(" *** temperature: ");
  //temperature readout
  Serial.print(readTemp());
  Serial.println(" degrees Celcius");
}

UPDATE: you can find my Arduino library here: https://github.com/geoffrey-vl/Easy_ADT7410_Arduino_Library

Self Synchronizing Wifi Clock, V2

Since my last encounter with a self synchronizing wifi clock I ended up learning how to implement my own display driver. Unfortunately the display died on me when testing it on a new power supply (which appeared to be malfunctioning afterwards) and so I have been thinking of porting my code to use the Adafruit 2.8″ display.  Pretty much most of the functionality remains from what I’ve made before, the most interesting thing I wanted to add this time was making use of the resistive touch screen. I could easily made a basic GUI to adjust settings and so on, but by some unknown reason I can’t get the touch positioning to work reliable on the Due board. Though it does function on Uno, Uno does not offer the needed program space (I’m at 40~50k). So, all together there is not much to it, but here is what I ended up with:

Next, I’ll check if there is the possibility to hook it up to Raspberry Pi and control it using NodeJS. Enjoy the holidays, see you in 2015!

Self Synchronizing Wifi Clock

In a previous serie of articles I showed you my progress in writing a Arduino Due driver for the Adafruit 16×32 LED matrix. Last few days I’ve focussed more on adding support for a simple font and displaying text characters, but actually during this implementation I discovered the solution behind 2 programming mistakes that were still left in the driver code. With this solved, I starting thinking about how to implement a font. After thinking of my own way of implementing this I also looked at how it was done in the original driver for Arduino Uno and actually some of the ideas matched. So I could really easy copy, adjust and implement the code for displaying characters, displaying ‘HELLO’ is now a matter of writing 6 lines of code!

After this I implemented code for reading a I2C compatible ADT7410 temperature sensor and use it for displaying the room temperature. Next I included and implemented code I’d already written before which allowed me to use the Adafruit C3300 (Wifi / SD) shield. The code connects the Arduino to the local WLAN and do NTP request to synchronize a software made clock with the internet. Furthermore it can also read and write data from/to an SD card. The SD card is used to hold the WLAN settings, it does this at boot time and it is only milliseconds later when it will use this data to configure and make the WiFi connection to you LAN. Voila, altogether there we have it: an Arduino based self synchronizing clock!

Progress: Adafruit 16×32 LED matrix on Arduino Due (5)

Past couple of days I’ve been working on abstracting and hiding the actual display driver code from the main Arduino project., this involves writing C++ code in an object oriented way. Although I’m used to work with objects in Java and C#, my experience with C++ classes, arrays  and pointers is rather limited. And so it took me quite some time to get it all working in an n-tier architecture, but in the end trial and error got me through it and at this moment it is working more or less okay. The phone camera is still taking messy pictures, but you get the picture I’d guess:

2014-04-12 11.43.17

 

The benefits from using this n-tier architecture is that now all driver code and display logic are concentrated in the same file, plus one can easily replace the driver without affecting code at other layers. While the color correctness is still not 100% working okay, my next goal is to add more logic that allows me to easily draw chars or circles or whatever. Furthermore it would also be great if I could send images over the serial bus and finally put some use to the driver I’ve been working on past few weeks. In the mean time also have a look at this guys project: http://bikerglen.com/projects/lighting/led-panel-1up/. He uses the same panel but instead uses an FPGA as hardware platform to drive the display. He clearly shows the power of FPGA’s in driving displays, to do the same in sequential microprocessor code things would get really complicated if not impossible to do.

Adafruit 16×32 LED matrix on Arduino Due (4)

I’m finally making some progress with introducing a higher color depth. Using BCM I’m now more or less on a 12-bit color depth. In the Adafruit driver I found parts of code that first were not very clear to me. There are methods like Color888(uint8_t r, uint8_t g, uint8_t b) and Color333(uint8_t r, uint8_t g, uint8_t b) but than I found that these are actually related to how colors are kept in memory bit wise. You see, with 333 colors you’re using 3 bits for the red value, 3 for green and 3 for blue. So this means there is a total bit depth of 0…7 for each RGB value resulting in a total 9-bit color depth which gives us 512 colors. 8/8/8 colors are 24-bit large in total and are the so called True Colors. They’re often used on PC’s in results in different colors. The 5/6/5 colors, also called High Colors, are 5+6+5 = 16 bits wide and result in 65536 different colors. This is also often used on computers. The awkwardness here is that the green portion has one bit extra compared to the red and blue portion. This is done because there was otherwise one bit unused (better to use it right!) and because of our perception is green is different that for red/blue one bit extra for green would be best suited (don’t ask me the exact scientifical reason, look for it on wikipedia). This 16-bit color depth is also used for storing images in the Adafruit driver. But so far it’s used only for storing, to display these images the driver falls back to a 12-bit color depth in 4/4/4 format and this because of two reasons. More colors would be kind of hard to do because it would dramatically reduce refresh rate and this you certainly don’t want. Although LEDs are used, refresh rates in between 25 and 50MHz are still not high enough for the human eye to experience the display as smooth. So it’s better to stuck at 12-bits deep. Also, in the 5/6/5 setup, if you use BCM modulation, there is one moment where you’ll be displaying only the green portion because red and blue are not equally in bit size.

But BCM, what is this exactly. BCM is a modulation technique like PWM is. With PWM you define the percentage of on and off time. Say you’re having a pulse of 70% on and 30% off during the total period, if you have a LED connected to that pulse you’ll experience it as slightly dimmed. With BCM you’re not giving any percentages, you’re using the bit value instead. Let’s say you’re using 2-bit BCM, for this the 2 bits are divided over the total period and so the more ‘1’s you have in your binary BCM value the more the LED will be pulsed on during the period, and the brighter it will look. Let’s say you’ve the value 11, the LED will be set on for the total period of time and will look very bright. 00 means it will be off all the time. But what about 01 and 10? Well, here the bit-value comes into play otherwise both codes would result in 50% on and 50% off. Using the bit-value the ‘1’ in ’10’ has a higher bit value than the ‘1’ in ’01’ and so it will stay on longer depending on the weight of the bit. There is a nice introduction to BCM found here.

And so the Adafruit driver uses 4-bit BCM, using only the 4 most significant bits of their 16-bit (5/6/5) representation in memory. I’ve gone the same direction and got it more or less functional:

2014-03-26-074234

This lowres picture doesn’t exactly show you a lot, I’ll have to look for better photo footage. The higher color depth is now possible using BCM but it’s still not finished yet. Resetting the timer each time kind of screws up the refresh rates so instead of using the due timer library I talked of before I’ll have to write the timer code myself and cut off an overhead. Also I noticed that I’m doing a lot of digital writes (6) to set just the RGB pins, where in the Adafruit driver they can set all 6 pins altogether. If a could do this it would also greatly reduce the timer interrupt time and allow me to bump up the refresh rate. So, more work ahead…

About Arduino’s DigitalWrite – Adafruit 16×32 LED matrix on Arduino Due (3)

In the previous article I already noticed how the display was starting to get less bright when I bumped up the refresh rate. Reading some parts of the Arduino Uno driver I noticed this one comment hinting to the slow Arduino DigitalWrite function. I never knew or red about this function not being very fast, I was expecting maybe a little impact but not as much as described in some online articles. And so I began to think of also looking for a way to faster manipulate pin outputs so that the driver works faster and better, and maybe allow us to do more than before. For Arduino Uno there is tons of information to find, however for Due you have to look a lot better. On the Arduino forums however I found this thread where faster port manipulation code has been presented:

inline void digitalWriteDirect(int pin, boolean val){
  if(val) g_APinDescription[pin].pPort -> PIO_SODR = g_APinDescription[pin].ulPin;
  else    g_APinDescription[pin].pPort -> PIO_CODR = g_APinDescription[pin].ulPin;
}

inline int digitalReadDirect(int pin){
  return !!(g_APinDescription[pin].pPort -> PIO_PDSR & g_APinDescription[pin].ulPin);
}

void setup() {                
  pinMode(13, OUTPUT);     
  pinMode(12, INPUT);     
  Serial.begin(9600);
}

void loop() {
  digitalWriteDirect(13, HIGH);   
  delay(1000);           
  digitalWriteDirect(13, LOW);    
  delay(1000);          
  Serial.println(digitalReadDirect(12));
}

In my current driver I swapped all digitalWrite methods with the digitalWriteDirect methods from above and than compared how fast writing one (double) row of LEDs goes. Time was measured by calling the micros() method before and after writing on row of data, taking the difference of both and next report back by doing a single Serial.write(). Here is a comparison:
digitalWriteDirect: 91us
digitalWrite: 661us
So as you can see the direct implementation gives us nearly 7 times better performance, or the other way around I kind nearly draw the entire display this time where before I could draw only one row. I also now noticed that in my display only the last rows of each half screen were illuminating very bright while others where nearly not illuminating at all. The reason is because now we switch so fast from one row to the next that the HIGH time of the pixels in a row is very small compared to before when using the slow Arduino implementation. The reason why the last row was however bright is because it get’s drawn as last and from here on it takes nearly 5000us before the next interrupt is being called, so it is really obvious that it was appearing really bright. In my last update I changed to drawing only one row per timer interrupt. This way rows get painted on a steady time base, and with using the faster digitalWriteDirect method we can easily bump up the refresh rate of the display so now the interrupt routine gets called 8 times more than before.
Next problem I get is that I need to call the interrupt code each 1250us in order to get a steady image. That is a 800MHz refresh rate per pixel row, and so 100Hz for the entire display, which kinds of bothers me because now interrupt code will interrupt normal program flow a lot of times, and I’m still at only 3 bit colors and I don’t have any support for dimming. I guess there is more reading ahead of me…

Adafruit 16×32 LED matrix on Arduino Due (2)

Not to much time spend so far on this display, but before I continued I wanted to make sure I can make the display illuminate asynchronously with the rest of the program flow. To do this we need to use interrupts which is launched after a certain timer expires. This way we can for example make sure that every 5ms the pixels are refreshed so that we get a clear non-flickering image. This also allows us to program our normal program code in the loop method without having to worry about the display code not being called in time (because then the display would go black for some time). For Arduino Uno the code is already there in the IDE to use, for Due a guy named Ivan Seidel already did some testing and programming and so we can also make use of interrupts on Due really easy (library on https://github.com/ivanseidel/DueTimer).

Here is a 3-bit colors version of the British flag displayed with the Adafruit 16×32 RGB LED matrix and Arduino Due.

2014-03-07 00.05.08I notice though that the LED’s do not really shine so powerful as they should, and also altering the interrupt timer to display at 50 or 100Hz intervals really ruins the picture (also this I can not explain). So more work ahead… may God save the Queen!