Skip to main content

GR-CITRUS Special Project: Sensing with Ruby

Overview

This page describes sensing using the GR-CITRUS mruby framework.


Preparation

Hardware

For this project, you will need the GR-CITRUS board, a USB cable (Micro B type), a jumper wire, a breadboard, and a sensor module. The sensor can be a trial-use version. As shown in the image here, the breadboard will be used to connect the USB cable to the GR-CITRUS board, so you will need either one large bread board, or two small pieces.

You will need four or five wires for one sensor module. If you are using a luminance sensor (photo transistor), you will not need the wires.


Software

We will be using Rubic for this project, so please familiarize yourself with the tool by referring to the "Starting Out with Rubic (Ruby Version)" project.

gr-citrus-board
usb-cable
citrus-sp-wire
citrus-sp-solderless-b
citrus-sp-solderless-s

Illuminance

This example uses the NJL7502 photo transistor.

peach-sp-sd-njl7502l


Pin Connections

Sensor GR-CITRUS
Anode 14
Cathode GND
citrus-sp-sensor-njl7502

Sample 1

This sample uses analogRead to perform sensing 100 times. To avoid having to connect an external resistor, the GR-CITRUS internal pull-up resistor is used, which means the brightness measurement will not be extremely accurate. The smaller the value, the brighter the light.

     
    usb = Serial.new(0)
    pinMode(14, 2) #INPUT_PULLUP
    100.times do
        usb.println(analogRead(14).to_s)
        delay(100)
    end 
    

Sample 2

This sample offers a higher resolution. Although the default setting is 0~675, the resolution power is 0~4096.

     
    usb = Serial.new(0)
    analogReference(3) #12bit mode
    pinMode(14, 2) #INPUT_PULLUP
    100.times do
        usb.println(analogRead(14).to_s)
        delay(100)
    end
    

Temperature and Humidity

This sample uses the HDC1000 temperature and humidity sensor module.

com-sp-hdc1000


Pin Connections

Sensor GR-CITRUS
+V 3.3V
SDA 5
SCL 6
RDY 2
GND GND

citrus-sp-sensor-hdc1000


Sample

This sample uses the I2C class to perform sensing 100 times.

      
    @ADDRESS   = 0x40
    @RDY_PIN   = 2
    @T_POINTER = 0x00
    @H_POINTER = 0x01
    @C_POINTER = 0x02
    @C_MSB     = 0x10
    @C_LSB     = 0x00
     
    usb = Serial.new(0)
    i2c2 = I2c.new(2)
    pinMode(@RDY_PIN, 0);
     
    i2c2.begin(@ADDRESS)
    i2c2.lwrite(@C_POINTER)
    i2c2.lwrite(@C_MSB)
    i2c2.lwrite(@C_LSB)
    i2c2.end(1)
     
    100.times do
      i2c2.begin(@ADDRESS);
      i2c2.lwrite(@T_POINTER)
      i2c2.end(1)
       
      while digitalRead(@RDY_PIN) == 1 do
      end
       
      i2c2.request(@ADDRESS, 4)
     
      t = i2c2.lread() << 8;
      t |= i2c2.lread();
      t = t / 65536.0 * 165.0 - 40.0
      
      h = i2c2.lread() << 8;
      h |= i2c2.lread();
      h = h / 65536.0 * 100.0
       
      usb.print("T:")
      usb.print(t.to_s)
      usb.print(" H:")
      usb.println(h.to_s)
       
      delay(100)
    end
    

Pin Connections: When Also Connecting WA-MIKAN

Pins 5 and 6 cannot be used when WA-MIKAN is also connected, so a separate I2C connection is employed. The following shows the sample using I2C1 (Wire1).

Sensor GR-CITRUS
+V 3.3V
SDA 0
SCL 1
RDY 2
GND GND

Sample

This sample uses I2C class with I2C1 to perform sensing 100 times.

       
    @ADDRESS   = 0x40
    @RDY_PIN   = 2
    @T_POINTER = 0x00
    @H_POINTER = 0x01
    @C_POINTER = 0x02
    @C_MSB     = 0x10
    @C_LSB     = 0x00
      
    usb = Serial.new(0)
    i2c = I2c.new(1)
    pinMode(@RDY_PIN, 0);
      
    i2c.begin(@ADDRESS)
    i2c.lwrite(@C_POINTER)
    i2c.lwrite(@C_MSB)
    i2c.lwrite(@C_LSB)
    i2c.end(1)
      
    100.times do
      i2c.begin(@ADDRESS);
      i2c.lwrite(@T_POINTER)
      i2c.end(1)
        
      while digitalRead(@RDY_PIN) == 1 do
      end
        
      i2c.request(@ADDRESS, 4)
      
      t = i2c.lread() << 8;
      t |= i2c.lread();
      t = t / 65536.0 * 165.0 - 40.0
       
      h = i2c.lread() << 8;
      h |= i2c.lread();
      h = h / 65536.0 * 100.0
        
      usb.print("T:")
      usb.print(t.to_s)
      usb.print(" H:")
      usb.println(h.to_s)
        
      delay(100)
    end 
    

Accelerometer

This sample uses the KXSC7-2050 acceleration sensing module.

acceleration-sensor-kxsc7


Pin Connections

Sensor GR-CITRUS
Vdd 3.3V
Mode 3.3V
ST/MOT GND
Enable 3.3V
Xout 14
Yout 15
Zout 16
GND GND
citrus-sp-sensor-kxsc7-2050

Sample

This sample uses a 12-bit analogRead to perform sensing 100 times, outputting a gravity-converted value.

       
    usb = Serial.new(0)
    @OFFSET = 1.65 / 3.3 * 4096 # 1.65V 0g
    @CONVERT = 3.3 / 4096 / 0.66 # 0.66V/g
    analogReference(3) #12bit
    100.times do
        x = (analogRead(14) - @OFFSET) * @CONVERT
        y = (analogRead(15) - @OFFSET) * @CONVERT
        z = (analogRead(16) - @OFFSET) * @CONVERT
         
        usb.print("x: ")
        usb.print(x.to_s)
        usb.print(" y: ")
        usb.print(y.to_s)
        usb.print(" z: ")
        usb.println(z.to_s)
        delay(100)
    end
    

Angular Rate

This sample uses the L3GD20 angular rate sensing module, with the I2C connection.

com-sp-l3gd20


Pin Connections

Sensor GR-CITRUS Notes
1:VDD 3.3V  
2:SCL 19 External pull-up required
3:SDA 18 External pull-up required
4:SA0 GND Address 0x6a
5:CS 3.3V I2C mode
INT2    
INT1    
GND GND  
citrus-sp-sensor-l3gd20

Sample

Copy and paste the GitHub sample to try this out.


Directional/Geomagnetic Sensing

This sample uses the HMC5883L digital compass, with the I2C connection.

digital-compass-hmc5883l


Pin Connections

Sensor GR-CITRUS Notes
1:VDD 3.3V  
2:SCL 6 Close JP1 for pull-up
3:SDA 5 Close JP1 for pull-up
4:GND GND  
5:RDY   Not used in sample
6:NC    
7:NC    
8:NC    
citrus-sp-sensor-hmc5883l

Sample

This sample uses the I2C class to perform sensing 100 times.

        
    #!mruby
    # Digital Compass Module HMC5883L
    # SCL -> 6
    # SDA -> 5
    # I2C Address(8bit): 0x3C(W)/0x3D(R)
    # I2C Address(7bit): 0x1E = (0x3C >> 1) || (0x3D >> 1)
     
    @ADDRESS   = 0x1E
    Usb = Serial.new(0)
    Hmc = I2c.new(2)
     
    #Set to continuous measurement mode.
    Hmc.write(@ADDRESS,0x02,0x00)
    #Hmc.begin(@ADDRESS)
    #Hmc.lwrite(0x02)
    #Hmc.lwrite(0x00)
    #Hmc.end()
    # ↓ When writing in 1 line ↓
    Hmc.write(@ADDRESS,0x02,0x00)
     
     
    100.times do
      Hmc.begin(@ADDRESS);
      Hmc.lwrite(0x03)
      Hmc.end()
      Hmc.request(@ADDRESS, 6)
     
      xH = Hmc.lread()
      xL = Hmc.lread()
      zH = Hmc.lread()
      zL = Hmc.lread()
      yH = Hmc.lread()
      yL = Hmc.lread()
     
      x = ((xH << 8) + xL) 
      x -= 0x10000 if (x >> 15) == 1
      y = ((yH << 8) + yL)
      y -= 0x10000 if (y >> 15) == 1
      z = ((zH << 8) + zL)
      z -= 0x10000 if (z >> 15) == 1
     
      Usb.println "x:"+x.to_s+" y:"+y.to_s+" z:"+z.to_s
       
      delay(100)
    end 
    

Pin Connections: When Also Connecting WA-MIKAN

Pins 5 and 6 cannot be used when WA-MIKAN is also connected, so a separate I2C connection is employed. The following shows the sample using I2C1 (Wire1).

Sensor GR-CITRUS Notes
1:VDD 3.3V  
2:SCL 1 Close JP1 for pull-up
3:SDA 0 Close JP1 for pull-up
4:GND GND  
5:RDY   Not used in sample
6:NC    
7:NC    
8:NC    

Sample

This sample uses the I2C class to perform sensing 100 times. Change the I2C channel to 1 to support I2c.new(1).

      
    #!mruby
    # Digital Compass Module HMC5883L
    # SCL -> 1
    # SDA -> 0
    # I2C Address(8bit): 0x3C(W)/0x3D(R)
    # I2C Address(7bit): 0x1E = (0x3C >> 1) || (0x3D >> 1)
     
    @ADDRESS   = 0x1E
    Usb = Serial.new(0)
    Hmc = I2c.new(1)
     
    #Set to continuous measurement mode.
    Hmc.write(@ADDRESS,0x02,0x00)
    #Hmc.begin(@ADDRESS)
    #Hmc.lwrite(0x02)
    #Hmc.lwrite(0x00)
    #Hmc.end()
    # ↓ When writing in 1 line ↓
    Hmc.write(@ADDRESS,0x02,0x00)
     
     
    100.times do
      Hmc.begin(@ADDRESS);
      Hmc.lwrite(0x03)
      Hmc.end()
      Hmc.request(@ADDRESS, 6)
     
      xH = Hmc.lread()
      xL = Hmc.lread()
      zH = Hmc.lread()
      zL = Hmc.lread()
      yH = Hmc.lread()
      yL = Hmc.lread()
     
      x = ((xH << 8) + xL) 
      x -= 0x10000 if (x >> 15) == 1
      y = ((yH << 8) + yL)
      y -= 0x10000 if (y >> 15) == 1
      z = ((zH << 8) + zL)
      z -= 0x10000 if (z >> 15) == 1
     
      Usb.println "x:"+x.to_s+" y:"+y.to_s+" z:"+z.to_s
       
      delay(100)
    end