My Cart

How to Represent Radiation Levels with a Servo and an RGB LED Using Radiation Geiger Kit

Difficulty Level: Expert -

1. Introduction

This tutorial allows the user to know radiation levels moving a servo like an analog meter, changing the RGB LED color and showing it on the LCD.

Ingredients:

    - 1 x Radiation Geiger Kit:
    • 1x Platform
    • 1x Geiger Counter - Radiation Sensor Board
    • 1x Servo
    • 3x 220Ω resistors
    • 1x RGB LED
    • 1x Breadboard
    • 1x External power supply
    • 1x Programming cable
    • Jumper Wires

Preparation Time: 30 minutes

Buy now
NOTE: Depending on the platform chosen to develop the project, the ingredients and the schematics shown in this tutorial can vary.

This project can be developed with Arduino or Intel Galileo. It is also compatible with Raspberry Pi using the Raspberry Pi to Arduino shields connection bridge.

For further information about the Geiger Counter - Radiation Sensor Board, consult the main tutorial.

Step 1: Connection

Connect the Geiger tube to the Radiation Sensor Board and then, connect the shield to the Arduino or to Raspberry Pi connection bridge. Connect the servo, the RGB LED with the resistors and the LCD in the breadboard as you can see in the next diagram.

Connect two wires, red and black, to the two long rows on the side of the breadboard to provide access to the 3.3 volt supply and ground. Connect all LCD pins to Radiation Sensor Board. Servo has 3 wires with different colors, connect Black/Brown wire of the servo to GND, Red wire to 3.3 volt and the remaining wire, Yellow/Orange, to digital pin 9. Finally connect pin A1, A2 and A3 to the RGB LED with a resistor in each pin and power it with 3.3 volt in the longest leg of the RGB LED.

Step 2: The Code

Arduino:

Code:
/*  
 *  Geiger Counter - Radiation Sensor Board
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           1.0
 *  Design:            David GascĂłn 
 *  Implementation:    Luis Miguel MartĂ­
 */
 
// include the library code:
#include <LiquidCrystal.h>
#include <Servo.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(3,4,5,6,7,8);
Servo needle;

// Threshold values for the led bar
#define TH1 45
#define TH2 95
#define TH3 200
#define TH4 400
#define TH5 600
//Colours
#define RED A1
#define GREEN A2
#define BLUE A3
// Conversion factor - CPM to uSV/h
#define CONV_FACTOR 0.00812

// Variables
int ledArray [] = {10,11,12,13,9};
int geiger_input = 2;
long count = 0;
long countPerMinute = 0;
long timePrevious = 0;
long timePreviousMeassure = 0;
long time = 0;
long countPrevious = 0;
float radiationValue = 0.0;


void setup(){
  pinMode(geiger_input, INPUT);
  digitalWrite(geiger_input,HIGH);
  for (int i=0;i<5;i++){
    pinMode(ledArray[i],OUTPUT);
  }

  Serial.begin(19200);

  //set up the LCD\'s number of columns and rows:
  lcd.begin(16, 2);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Radiation Sensor");
  lcd.setCursor(0,1);
  lcd.print("Board - Arduino");  
  delay(1000);

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(" Cooking Hacks");
  delay(1000);

  lcd.clear();
  lcd.setCursor(0,1);  
  lcd.print("www.cooking-hacks.com");
  delay(500);
  for (int i=0;i<5;i++){
    delay(200);  
    lcd.scrollDisplayLeft();
  }
  delay(500);

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("  - Libelium -");
  lcd.setCursor(0,1);
  lcd.print("www.libelium.com");    
  delay(1000);

  lcd.clear();  
  lcd.setCursor(0, 0);
  lcd.print("CPM=");
  lcd.setCursor(4,0);
  lcd.print(6*count);
  lcd.setCursor(0,1);
  lcd.print(radiationValue);

  attachInterrupt(0,countPulse,FALLING);
  needle.attach(9);
}

void loop(){
  
  if (millis()-timePreviousMeassure > 10000){
    countPerMinute = 6*count;
    radiationValue = countPerMinute * CONV_FACTOR;
    timePreviousMeassure = millis();
    Serial.print("cpm = "); 
    Serial.print(countPerMinute,DEC);
    Serial.print(" - ");
    Serial.print("uSv/h = ");
    Serial.println(radiationValue,4);      
    lcd.clear();    
    lcd.setCursor(0, 0);
    lcd.print("CPM=");
    lcd.setCursor(4,0);
    lcd.print(countPerMinute);
    lcd.setCursor(0,1);
    lcd.print(radiationValue,4);
    lcd.setCursor(6,1);
    lcd.print(" uSv/h");
    
    //led var setting  
    if(countPerMinute <= TH1) ledVar(0);
    if((countPerMinute <= TH2)&&(countPerMinute>TH1)){
      ledVar(1);
      digitalWrite(RED,LOW);
      digitalWrite(GREEN,LOW);
      digitalWrite(BLUE,LOW);
    }
    if((countPerMinute <= TH3)&&(countPerMinute>TH2)){
      ledVar(2);
      digitalWrite(RED,LOW);
      digitalWrite(GREEN,LOW);
      digitalWrite(BLUE,HIGH);
    }
    if((countPerMinute <= TH4)&&(countPerMinute>TH3)){
      ledVar(3);
      digitalWrite(RED,LOW);
      digitalWrite(GREEN,HIGH);
      digitalWrite(BLUE,LOW);
    }
    if((countPerMinute <= TH5)&&(countPerMinute>TH4)){
      ledVar(4);
      digitalWrite(RED,HIGH);
      digitalWrite(GREEN,LOW);
      digitalWrite(BLUE,LOW);
    }
    if(countPerMinute>TH5){
      ledVar(5);
      digitalWrite(RED,HIGH);
      digitalWrite(GREEN,HIGH);
      digitalWrite(BLUE,HIGH);
    }

    count = 0;
  }
  needle.write(int(countPerMinute));
}

void countPulse(){
  detachInterrupt(0);
  count++;
  while(digitalRead(2)==0){
  }
  attachInterrupt(0,countPulse,FALLING);
}

void ledVar(int value){
  if (value > 0){
    for(int i=0;i<=value;i++){
      digitalWrite(ledArray[i],HIGH);
    }
    for(int i=5;i>value;i--){
      digitalWrite(ledArray[i],LOW);
    }
  }
  else {
    for(int i=5;i>=0;i--){
      digitalWrite(ledArray[i],LOW);
    }
  }
}


        

Raspberry Pi:

Code:
/*  
 *  Geiger Counter - Radiation Sensor Board
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           1.0
 *  Design:            David GascĂłn 
 *  Implementation:    Jorge Casanova, Luis MartĂ­n
 */
 
// include the library code:
#include "arduPi.h"


// Threshold values for the led bar
#define TH1 45
#define TH2 95
#define TH3 200
#define TH4 400
#define TH5 600
//Colours
#define RED 1
#define GREEN 2
#define BLUE 3
// Conversion factor - CPM to uSV/h
#define CONV_FACTOR 0.00812

// Variables
unsigned int us;

int SERVO = 9;
int grados;

int ledArray [] = {10,11,12,13,9};
int geiger_input = 2;
long count = 0;
long countPerMinute = 0;
long timePrevious = 0;
long timePreviousMeassure = 0;

long countPrevious = 0;
float radiationValue = 0.0;

void countPulse();
void ledVar(int value);
void Servo(int grados);


void setup(){
	
  pinMode(RED, OUTPUT);
  pinMode(GREEN, OUTPUT);
  pinMode(BLUE, OUTPUT);
  pinMode(geiger_input, INPUT);
  digitalWrite(geiger_input,HIGH);
  for (int i=0;i<5;i++){
	pinMode(ledArray[i],OUTPUT);
  }
  
  printf("Radiation Sensor\n");
 
  printf("Board - Arduino\n");  
  delay(1000);

  
  printf(" Cooking Hacks\n");
  delay(1000);

   
  printf("www.cooking-hacks.com\n");
  delay(500);
  
  printf(" - Libelium -\n");
  
  printf("www.libelium.com\n");    
  delay(1000);

   
  
  printf("CPM = %i\n",6*count);
  printf("%f uSv/h\n",radiationValue);
  
  attachInterrupt(2,countPulse,FALLING);

}

void loop(){
  
  if (millis()-timePreviousMeassure > 10000){
    countPerMinute = 6*count;
    radiationValue = countPerMinute * CONV_FACTOR;
    timePreviousMeassure = millis();
   
    printf("CPM = %i\n",countPerMinute);
    printf("%f uSv/h\n",radiationValue);
    
    //led var setting  
    if(countPerMinute <= TH1) ledVar(0);
    if((countPerMinute <= TH2)&&(countPerMinute>TH1)){
      ledVar(1);
      digitalWrite(RED,LOW);
      printf("www.libelium.com\n");
      digitalWrite(GREEN,LOW);
      digitalWrite(BLUE,LOW);
    }
    if((countPerMinute <= TH3)&&(countPerMinute>TH2)){
      ledVar(2);
      digitalWrite(RED,LOW);
      digitalWrite(GREEN,LOW);
      digitalWrite(BLUE,HIGH);
      printf("www.libelium.com\n");
    }
    if((countPerMinute <= TH4)&&(countPerMinute>TH3)){
      ledVar(3);
      digitalWrite(RED,LOW);
      digitalWrite(GREEN,HIGH);
      digitalWrite(BLUE,LOW);
      printf("www.libelium.com\n");
    }
    if((countPerMinute <= TH5)&&(countPerMinute>TH4)){
      ledVar(4);
      digitalWrite(RED,HIGH);
      digitalWrite(GREEN,LOW);
      digitalWrite(BLUE,LOW);
      printf("www.libelium.com\n");
    }
    if(countPerMinute>TH5){
      ledVar(5);
      digitalWrite(RED,HIGH);
      digitalWrite(GREEN,HIGH);
      digitalWrite(BLUE,HIGH);
      printf("www.libelium.com\n");
    }

    count = 0;
  }
  int tiempo = millis();
   while (millis()-tiempo < 1000) {
          Servo(countPerMinute);
	  }
}

void countPulse(){
  
  count++;
  
}

void ledVar(int value){
  if (value > 0){
    for(int i=0;i<=value;i++){
      digitalWrite(ledArray[i],HIGH);
    }
    for(int i=5;i>value;i--){
      digitalWrite(ledArray[i],LOW);
    }
  }
  else {
    for(int i=5;i>=0;i--){
      digitalWrite(ledArray[i],LOW);
    }
  }
}

void Servo(int grados){
 
    us = (grados*11) + 500;      // Convert angle to microseconds
    digitalWrite(SERVO, HIGH);
    delayMicroseconds(us);
    digitalWrite(SERVO, LOW);
    delay(50);                   // Refresh cycle of servo

}


int main (){
	setup();
	while(1){
		loop();
	}
	return (0);
}

        

Intel Galileo:

Code:
/*  
 *  Geiger Counter - Radiation Sensor Board
 *  
 *  Copyright (C) Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *  
 *  Version:           1.0
 *  Design:            David GascĂłn 
 *  Implementation:    Jorge Casanova, Luis MartĂ­n
 */

// include the library code:
#include <LiquidCrystal.h>
#include <Servo.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(3,4,5,6,7,8);
Servo needle;

// Threshold values for the led bar
#define TH1 45
#define TH2 95
#define TH3 200
#define TH4 400
#define TH5 600
//Colours
#define RED 1
#define GREEN 2
#define BLUE 3
// Conversion factor - CPM to uSV/h
#define CONV_FACTOR 0.00812

// Variables
int ledArray [] = {10,11,12,13,9};
int geiger_input = 2;
long count = 0;
long countPerMinute = 0;
long timePrevious = 0;
long timePreviousMeassure = 0;

long countPrevious = 0;
float radiationValue = 0.0;


void setup(){
  pinMode(geiger_input, INPUT);
  digitalWrite(geiger_input,HIGH);
  for (int i=0;i<5;i++){
    pinMode(ledArray[i],OUTPUT);
  }

  Serial.begin(19200);

  //set up the LCD\'s number of columns and rows:
  lcd.begin(16, 2);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Radiation Sensor");
  lcd.setCursor(0,1);
  lcd.print("Board - Arduino");  
  delay(1000);

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(" Cooking Hacks");
  delay(1000);

  lcd.clear();
  lcd.setCursor(0,1);  
  lcd.print("www.cooking-hacks.com");
  delay(500);
  for (int i=0;i<5;i++){
    delay(200);  
    lcd.scrollDisplayLeft();
  }
  delay(500);

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("  - Libelium -");
  lcd.setCursor(0,1);
  lcd.print("www.libelium.com");    
  delay(1000);

  lcd.clear();  
  lcd.setCursor(0, 0);
  lcd.print("CPM=");
  lcd.setCursor(4,0);
  lcd.print(6*count);
  lcd.setCursor(0,1);
  lcd.print(radiationValue);

  attachInterrupt(2,countPulse,FALLING);
  needle.attach(9);
}

void loop(){
  
  if (millis()-timePreviousMeassure > 10000){
    countPerMinute = 6*count;
    radiationValue = countPerMinute * CONV_FACTOR;
    timePreviousMeassure = millis();
    Serial.print("cpm = "); 
    Serial.print(countPerMinute,DEC);
    Serial.print(" - ");
    Serial.print("uSv/h = ");
    Serial.println(radiationValue,4);      
    lcd.clear();    
    lcd.setCursor(0, 0);
    lcd.print("CPM=");
    lcd.setCursor(4,0);
    lcd.print(countPerMinute);
    lcd.setCursor(0,1);
    lcd.print(radiationValue,4);
    lcd.setCursor(6,1);
    lcd.print(" uSv/h");
    
    //led var setting  
    if(countPerMinute <= TH1) ledVar(0);
    if((countPerMinute <= TH2)&&(countPerMinute>TH1)){
      ledVar(1);
      digitalWrite(RED,LOW);
      digitalWrite(GREEN,LOW);
      digitalWrite(BLUE,LOW);
    }
    if((countPerMinute <= TH3)&&(countPerMinute>TH2)){
      ledVar(2);
      digitalWrite(RED,LOW);
      digitalWrite(GREEN,LOW);
      digitalWrite(BLUE,HIGH);
    }
    if((countPerMinute <= TH4)&&(countPerMinute>TH3)){
      ledVar(3);
      digitalWrite(RED,LOW);
      digitalWrite(GREEN,HIGH);
      digitalWrite(BLUE,LOW);
    }
    if((countPerMinute <= TH5)&&(countPerMinute>TH4)){
      ledVar(4);
      digitalWrite(RED,HIGH);
      digitalWrite(GREEN,LOW);
      digitalWrite(BLUE,LOW);
    }
    if(countPerMinute>TH5){
      ledVar(5);
      digitalWrite(RED,HIGH);
      digitalWrite(GREEN,HIGH);
      digitalWrite(BLUE,HIGH);
    }

    count = 0;
   needle.write(int(countPerMinute));  
}
  
  
}

void countPulse(){
 count = 0;
  timePreviousMeassure = millis();
  while (millis()-timePreviousMeassure < 10000)
  {
    if(digitalRead(geiger_input) == 0)
    {
      count++;
      while(digitalRead(geiger_input) == 0); // do nothing until pin goes back to HIGH
    }
  }
}

void ledVar(int value){
  if (value > 0){
    for(int i=0;i<=value;i++){
      digitalWrite(ledArray[i],HIGH);
    }
    for(int i=5;i>value;i--){
      digitalWrite(ledArray[i],LOW);
    }
  }
  else {
    for(int i=5;i>=0;i--){
      digitalWrite(ledArray[i],LOW);
    }
  }
}