Multifunction shield for Arduino Uno (HCARDU0085)

andrew
Site Admin
Posts: 1374
Joined: Sun Aug 05, 2012 4:15 pm

Re: Multifunction shield for Arduino Uno (HCARDU0085)

Post by andrew » Tue Jun 10, 2014 7:49 am

We've gone through our stock and we have found that some shields don't have the seven segment module pins cropped enough so will come into contact with the USB connector when fully inserted. Unfortunately you must have one of these. However most of the shields we have checked are OK when the shield fully inserted. If this isn't done on these shields they can be tilted to one side which would allow them to make contact. I've put a note of the forum in the description to check for this which will shortly be added to the various listing pages.
Comments made by this poster do not necessarily reflect the views of Hobby Components Ltd.

barewires
Posts: 49
Joined: Wed Aug 21, 2013 7:38 am

Re: Multifunction shield for Arduino Uno (HCARDU0085)

Post by barewires » Wed Jun 11, 2014 2:54 pm

gadjet wrote:Looking at the schematic, it looks like it doesn't have decimal point support, is that correct?
An alternate segment map is required for the affected digit. Try this and see all DP turned on.
const byte SEGMENT_MAP[] = {0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0X00,0X10}; // msb (most significant bit) is DP segment 'h'

gadjet
Posts: 25
Joined: Thu Mar 13, 2014 12:46 pm

Re: Multifunction shield for Arduino Uno (HCARDU0085)

Post by gadjet » Wed Jun 11, 2014 3:19 pm

Thanks,
at the moment I only need one digit to have a decimal point and therefore I just AND the required digit with 0x7f and that switches on the DP for just that digit position whatever the number is.

barewires
Posts: 49
Joined: Wed Aug 21, 2013 7:38 am

Re: Multifunction shield for Arduino Uno (HCARDU0085)

Post by barewires » Wed Jun 11, 2014 3:56 pm

To turn on a designated Decimal Point, the segment map can be expanded with ten more values. Simply replace the following lines. A-OK on the 0x7F mask, I posted and then read your comments. We all can benefit from this forum.

const byte SEGMENT_MAP[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0X80,0X90,0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0X00,0X10}; // msb is DP

WriteNumberToSegment(2 , ((Number / 10) % 10)+10); // turn on selected DP by adding decimal 10 to the value.

gadjet
Posts: 25
Joined: Thu Mar 13, 2014 12:46 pm

Re: Multifunction shield for Arduino Uno (HCARDU0085)

Post by gadjet » Wed Jun 11, 2014 7:38 pm

You're dead right, it's good to get as much information on the forum as possible and there's always more than one way to skin a cat :D

barewires
Posts: 49
Joined: Wed Aug 21, 2013 7:38 am

Re: Multifunction shield for Arduino Uno (HCARDU0085)

Post by barewires » Sun Jun 15, 2014 1:02 pm

Playing with the DS18B20 1-Wire Digital Thermometer required a bit of research. One could make a career out of this one chip. :geek:

The TO-92 chip sits in the 3 machined sockets U5 closest to J1 jumper. J1 feeds 5v to a 10k resistor R5 and the centre pin DQ.

The silkscreen layout is correct with the flat side facing the bottom side of the board towards the 3 pushbuttons.
The designation "U5-18b20-LM35-A4" has an arrow pointing up toward the centre DQ data pin. Gnd on the left, +5 on the right. DQ data is on pin A4.

"Each DS18B20 contains a unique 64–bit code stored in ROM. The least significant 8 bits
of the ROM code contain the DS18B20’s 1-Wire family code: 28h. The next 48 bits contain a unique
serial number. The most significant 8 bits contain a cyclic redundancy check (CRC) byte that is
calculated from the first 56 bits of the ROM code." The serial monitor output is shown below: R= 28 is the family code.

Byte 0 and byte 1 of the scratchpad contain the LSB and the MSB of the temperature register respectively.
P= 01 A2 is 0x01A2 = 418 decimal x 0.0625 = 26.125 degrees C, increases to 0x01A3 on the next sample.

Sample Monitor Dump:
R= 28 32 6A B9 05 00 00 06 Device is a DS18B20 family device.
P= 01 A2 01 4B 46 7F FF 0E 10 D8 CRC=D8
No more addresses.
R= 28 32 6A B9 05 00 00 06 Device is a DS18B20 family device.
P= 01 A3 01 4B 46 7F FF 0D 10 CE CRC=CE
No more addresses.

Four of my devices (out of a possible 127) :shock: in parallel shows unique serial numbers and temperatures within 3 units:
R= 28 32 6A B9 05 00 00 06 Device is a DS18B20 family device.
P= 01 8E 01 4B 46 7F FF 02 10 02 CRC=2
R= 28 8A 84 B9 05 00 00 D8 Device is a DS18B20 family device.
P= 01 90 01 4B 46 7F FF 10 10 92 CRC=92
R= 28 89 5D B9 05 00 00 2C Device is a DS18B20 family device.
P= 01 8F 01 4B 46 7F FF 01 10 14 CRC=14
R= 28 1F 5E B9 05 00 00 61 Device is a DS18B20 family device.
P= 01 8E 01 4B 46 7F FF 02 10 02 CRC=2
No more addresses.

The latest version of the OneWire library is on Paul Stoffregen's site.
http://www.pjrc.com/teensy/td_libs_OneWire.html

Code taken from http://playground.arduino.cc/Learning/OneWire

Code: Select all

//Start of Arduino Code modified by barewires 15062014
#include <OneWire.h>

// DS18B20 Temperature chip i/o
OneWire ds(18);  // on pin A4 

void setup(void) {
  // initialize inputs/outputs
  // start serial port
  Serial.begin(9600);
}

void loop(void) {
  byte i;
  byte present = 0;
  byte data[12];
  byte addr[8];

  if ( !ds.search(addr)) {
      Serial.print("No more addresses.\n");
      ds.reset_search();
      return;
  }

  Serial.print("R= ");
  for( i = 0; i < 8; i++) {
     if (addr[i] <16) 
    {  
      Serial.print("0");
    }
    Serial.print(addr[i], HEX);
    Serial.print(" ");
  }

  if ( OneWire::crc8( addr, 7) != addr[7]) {
      Serial.print("CRC is not valid!\n");
      return;
  }

  if ( addr[0] == 0x10) {
      Serial.print("    Device is a DS18S20 family device.\n");
  }
  else if ( addr[0] == 0x28) {
      Serial.print("    Device is a DS18B20 family device.\n");
  }
  else {
      Serial.print("    Device family is not recognized: 0x");
      Serial.println(addr[0],HEX);
      return;
  }

  ds.reset();
  ds.select(addr);
  ds.write(0x44,1);         // start conversion, with parasite power on at the end

  delay(1000);     // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.

  present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // Read Scratchpad

  Serial.print("P= ");
  if (present <16) 
    {  
      Serial.print("0");
    }
  Serial.print(present,HEX);
  Serial.print(" ");
  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
    if (data[i] <16) 
    {  
      Serial.print("0");
    }
    Serial.print(data[i], HEX);
    Serial.print(" ");
  }
  Serial.print(" CRC=");
  Serial.print( OneWire::crc8( data, 8), HEX);
  Serial.println();

}
Last edited by barewires on Sun Jul 20, 2014 11:08 am, edited 2 times in total.

linker3000
Posts: 5
Joined: Mon Jun 23, 2014 9:26 pm

DS18B20 Code for 7 segment display

Post by linker3000 » Sat Jul 05, 2014 6:47 pm

Hi everyone,

I am really new to Arduino so I purchased a Uno and this shield for learning. My first effort has been to merge some code for a DS18B20 temperature sensor and the 7 segment display. The resulting sketch is below - it uses a timer interrupt routine to keep the display refreshed and bright. Suggestions for improvements are most welcome.

The sketch comments include additional notes - for example, you need to install the OneWire library to read the temperature sensor.

Code: Select all

/* FILE:    ARD_Multifunction_Shield_Temp_7Seg
 DATE:    18-Jul-2014
 VERSION: 0.3
 AUTHOR:  N. Kendrick
 
 REVISIONS: 0.1 05-Jul-2014 First Release
            0.2 17-Jul-2014 Added back 750mS delay in routine that reads chip temperature to match design specs
                            Changed main loop delay to 4 sec so, overall, chip temp is read approx every 5 secs
                            Initial setting for display is 88.88 as a lamp test
            0.3 18-Jul-2014 Changed the delay timing values to achieve a temp update approx every 10 secs
                            Displays 99.99 on error/unable to read sensor
 
 This is an example of how to use Hobby Components Arduino compatible Multi
 Function experimenter shield (HCARDU0085), fitted with a (optional) DS18B20
 1-wire digital temperature sensor in socket U5.
 
 The main loop of this sketch reads the temperature sensor approximately every 250mS and updates a variable
 with the reading. In the background, an interrupt routine is constantly reading this value and displaying
 it on the 7-segment LED display.
 
 This code is based on the original 7-Segment sketch example from HobbyComponents.com together with
 interrupt servicing code from http://www.instructables.com/id/Arduino-Timer-Interrupts/ which was
 released under the terms of the GPL3 licence.
 
 OneWire code located at various sources, including: http://forum.arduino.cc/index.php?topic=143382.0
 
 To compile this sketch, download and install the OneWire library from here:
 http://www.pjrc.com/teensy/td_libs_OneWire.html
 
 You may copy, alter and reuse this code in any way you like, but please leave
 reference to HobbyComponents.com and the author in your comments if you redistribute this code.
 This software may not be used for the purpose of promoting or selling products
 that directly compete with Hobby Components Ltd's own range of products.
 
 NOTES:
 
 This version of the sketch sets a fixed decimal point, so assumes the input temperature is in the range 00.00-99.00C.
 
 THIS SOFTWARE IS PROVIDED "AS IS". HOBBY COMPONENTS AND THE AUTHOR MAKE NO WARRANTIES, WHETHER
 EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ACCURACY OR LACK OF NEGLIGENCE.
 HOBBY COMPONENTS SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR ANY DAMAGES,
 INCLUDING, BUT NOT LIMITED TO, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY
 REASON WHATSOEVER.
 */

#include <OneWire.h>

int DS18S20_Pin = 18; //DS18S20 Signal pin on A4 (pin 18)

//Stores the value for the 7-segment display
//Initial setting turns on all segments as a lamp test
int Number = 8888;

//Can be used to set the position of the decimal point on the LED display - in this example code, the DP is fixed
int Dec_one;
int Dec_two;
int Dec_three;
int Dec_four;

//Temperature chip i/o
OneWire ds(DS18S20_Pin);  // on pin A4

//7-Seg definitions
/* Define shift register pins used for seven segment display */
#define LATCH_DIO 4
#define CLK_DIO 7
#define DATA_DIO 8

/* Segment byte maps for numbers 0 to 9 */
//This map is the revised version of the map that adds decimal point support. There is also an additional map
//(highest value in the map) for a blank segment display, but it is not used in this sketch
const byte SEGMENT_MAP[] = {
  0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0X80,0X90,0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0X00,0X10,0XFF}; // msb is DP
/* Byte maps to select digit 1 to 4 */
const byte SEGMENT_SELECT[] = {
  0xF1,0xF2,0xF4,0xF8};

void setup(void) {

  cli(); //Stop interrupts during setup

  //Set timer1 interrupt at 205Hz (when OCR1A = 75)
  TCCR1A = 0;// set entire TCCR1A register to 0
  TCCR1B = 0;// same for TCCR1B
  TCNT1  = 0;//initialize counter value to 0
  //The next value sets the interrupt frequency, which determines how often the LED display is refreshed.
  //A value of 75 gives an interrupt frequency of just over 200Hz. The frequency is calculated with:
  //f = (16*10^6) / (OCR1A value * 1024) - 1. The value used for OCR1A must be less than 65536.
  OCR1A = 75;
  //Turn on CTC mode
  TCCR1B |= (1 << WGM12);
  //Set CS10 and CS12 bits for 1024 prescaler
  TCCR1B |= (1 << CS12) | (1 << CS10);
  //Enable timer compare interrupt
  TIMSK1 |= (1 << OCIE1A);

  //Initialise the 7 segment display
  /* Set DIO pins to outputs */
  pinMode(LATCH_DIO,OUTPUT);
  pinMode(CLK_DIO,OUTPUT);
  pinMode(DATA_DIO,OUTPUT);

  sei(); //Allow interrupts now
}

void loop(void) {

  //Store the current temperature * 100
  Number=(int(getTemp()*100));
  delay (500); // Add this to the delays incurred during the LED refresh and we update the display roughly every 10 sec
}

float getTemp(){
  //returns the temperature from one DS18S20 in DEG Celsius

  byte data[12];
  byte addr[8];

  if ( !ds.search(addr)) {
    //no more sensors on chain, reset search
    ds.reset_search();
    return 99.99;
  }

  if ( OneWire::crc8( addr, 7) != addr[7]) {
    return 99.99;
  }

  if ( addr[0] != 0x10 && addr[0] != 0x28) {
    return 99.99;
  }

  ds.reset();
  ds.select(addr);
  ds.write(0x44,1); // start conversion, with parasite power on at the end

  delay(750); // Wait for chip to generate the result (750mS max at 12-bit resolution)

  byte present = ds.reset();
  ds.select(addr);   
  ds.write(0xBE); // Read Scratchpad

  for (int i = 0; i < 9; i++) { // we need 9 bytes
    data[i] = ds.read();
  }

  ds.reset_search();

  byte MSB = data[1];
  byte LSB = data[0];

  float tempRead = ((MSB << 8) | LSB); //using two's compliment
  float TemperatureSum = tempRead / 16;

  return TemperatureSum;
}
// Routines for 7 segment display

//Interrupt routine to update 7-segment display

ISR(TIMER1_COMPA_vect){//timer0 interrupt
  /* Write a decimal number between 0 and 9999 to the display */

  //Sets where the decimal point should be illuminated - only using a fixed
  //position in this sketch.
  Dec_one = 0;
  Dec_two = 10;
  Dec_three = 0;
  Dec_four = 0;

  //Write out the four digits and keep them illuminated for 10mS otherwise they look dim.
  WriteNumberToSegment(0 , (Number / 1000) + Dec_one);
  delay(10);
  WriteNumberToSegment(1 , ((Number / 100) % 10) + Dec_two);
  delay(10);
  WriteNumberToSegment(2 , ((Number / 10) % 10) + Dec_three);
  delay(10);
  WriteNumberToSegment(3 , (Number % 10) + Dec_four);
  delay(10);
}

/* Write a decimal number between 0 and 9 to one of the 4 digits of the display */
void WriteNumberToSegment(byte Segment, byte Value) {
  digitalWrite(LATCH_DIO,LOW);
  shiftOut(DATA_DIO, CLK_DIO, MSBFIRST, SEGMENT_MAP[Value]);
  shiftOut(DATA_DIO, CLK_DIO, MSBFIRST, SEGMENT_SELECT[Segment] );
  digitalWrite(LATCH_DIO,HIGH);   
}

Last edited by linker3000 on Fri Jul 18, 2014 8:26 pm, edited 9 times in total.

andrew
Site Admin
Posts: 1374
Joined: Sun Aug 05, 2012 4:15 pm

Re: Multifunction shield for Arduino Uno (HCARDU0085)

Post by andrew » Sun Jul 06, 2014 10:08 am

You may find our HCTimer2 library of use to you. You can download it here:

http://forum.hobbycomponents.com/viewto ... =43&t=1336

This re-tasks one of the hardware timers to run code in the background at regular intervals. There's a blink example that shows how it works and will give you an idea on how you may be able to use it to run the code for updating the display outside of the main loop.
Comments made by this poster do not necessarily reflect the views of Hobby Components Ltd.

linker3000
Posts: 5
Joined: Mon Jun 23, 2014 9:26 pm

Re: Multifunction shield for Arduino Uno (HCARDU0085)

Post by linker3000 » Sun Jul 06, 2014 6:51 pm

andrew wrote:You may find our HCTimer2 library of use to you. You can download it here:

http://forum.hobbycomponents.com/viewto ... =43&t=1336

This re-tasks one of the hardware timers to run code in the background at regular intervals. There's a blink example that shows how it works and will give you an idea on how you may be able to use it to run the code for updating the display outside of the main loop.
Thanks Andrew - I modified my original post as I worked out a timer-based interrupt routine, but I will take a look at the code you suggest too.

linker3000
Posts: 5
Joined: Mon Jun 23, 2014 9:26 pm

Re: Multifunction shield for Arduino Uno (HCARDU0085)

Post by linker3000 » Wed Jul 16, 2014 4:06 pm

I FRIED YOUR BOARD!!!

Well, not actually!

We have an industrial oven at work that's used to heat test consumer electronics for failure analysis and development testing. The oven was in use the other day so I took the opportunity to pop in a Uno plus the multifunction shield fitted with a DS18B20 temperature sensor, and running the code I recently posted. You can dial up any temperature you want and the oven will oblige to within 1C. I took the board up to 40C and then down by a few steps, leaving everything to settle for 10 mins before taking readings - here's a picture and the results:

Image

Temperature readings were as follows:

Arduino ---- Oven Sensor reading

40.43 ---- 40.60
32.37 ---- 31.80
27.40 ---- 26.60
20.50 ---- 19.50

Not bad!

Post Reply

Return to “Arduino Shields”