Mission Accomplished

My first CyanogenMod new (little) feature is born. Today I’ve finished the “Development shortcut” project. It enables the wipe data and application force close option in the recent tasks list and in the notification area. These options will be available only if the Development mode is enabled.

device-2013-11-02-140109 device-2013-11-02-140037

The first version is only for Motorola defy mb525 and is available on my github repo. I do a pull request to Quarx2k in order to merge my mod in his “official” Motorola repo.

The next step is to merge it in the official CM dev branch and submit it to gerrit review. But the first CyanogenmMod 10.2 M build is coming (this weekend) with the code freeze phase. I have to be quick!

 

Start android AOSP – CyanogenMod development : the firsts steps

I’m still waiting for my 9$ Arduino…some mistake in Hong Kong customs procedure has generated a huge delay in shipment.

But finally I found an “idea” for some Cyanogen development, and I want to share here the steps that I’m doing.

The Goal

At work I’m working on a feature that requires frequent “Force stop” and “Clear data” during the debug and development phase. I want to improve the “Application info” popup menu on the notification area (long click on the app notification) in order to add two new item: “Force Stop” and “Clear data”.

The Player

    • At the moment the Nexus S is not available, so I will use the ugliest android phone ever seen: the Motorola Defy (MB 526), aka “Jordan” – specs (From GSM arena)

image

    • I will use the CyanogenMod fork by Quarx2k, based on Android JB 4.1.2 – XDA forum post
    • My old development machine @ work – a Dell studio XPS with Ubuntu 12.04 LTS

image

Step 0 : setup the development environment

Simply follow the post on XDA forum. After a few hours you should have your standard build from JB sources

Step 1 : setup a new github repo

I need to modify the “frameworks/base” project, because the notification area sources are in “frameworks/base/packages/SystemUI” folder.  Simply go to “https://github.com/Quarx2k/android_frameworks_base” and fork this repository. My forked repo location is “https://github.com/sarbyn/android_frameworks_base_jordan

Now you need to add a “local_manifest.xml” in your .repo/local_manifests folder, in which you must define the new repository:

<?xml version="1.0" encoding="UTF-8"?>
   <manifest>
   <remove-project name="Quarx2k/android_frameworks/base"/>
   <project remote="github" path="frameworks/base" name="sarbyn/android_frameworks_base_jordan" revision="jellybean"/>
</manifest>

A simple explanation (from CM wiki)

  • remote — the name of the remote. this can be one that was defined in either the regular manifest or local_manifest.xml.
  • name — the name of the git project– for github it has the format account_name/project_name.
  • path — where the git repository should go in your local copy of the source code.
  • revision — (OPTIONAL) which branch or tag to use in the repository.

Now you are ready to “repo sync” your source tree.

Step 2 : start editing

Before you change anything you need to start a new git branch. Go into the main project folder and do a “repo start banchname frameworks/base“. Now you are ready to modify the code in a new git branch.

Step 3 : build

When all the development is done, do a full build with the standard procedure

source build/envsetup.sh && brunch mb526
make -j# bacon

# represents double the cores you have on your computer

Step 4 : commit and push on github repo

Enter in frameworks/base and check the repo status with git status. Add all the modified files with the standard git add FILENAME and commit the changes with git commit -m ‘message’. Now you are ready to upload the new git branch on server git push -u github branch_name

Step 5 : backup & install

The last step is very simple: go into recovery mode and do a full Nandroid backup. After that you can flash your build and try if it works 🙂

EUREKA!

EUREKA!

 

Thermistor sample code for Arduino – Raspberry

This is a C++ class for a simple NTC thermistor. I used the thermistor included in the cooking-hacks.com starter kit (datasheet) and the cooking-hacks.com Raspebby to Arduino shield, but this sample is easily adaptable for any NTC thermistor or also for Arduino platform. It can be used with another NTC thermistor: simply change the BasicThermistor.h values:

  • BETA (o B-Value) : the beta value of thermistor
  • THERMISTOR: zero power resistance at 25° C
BasicThermistor schema

BasicThermistor schema

Some notes:

  • This class is designed for a read every 10 seconds.
  • Check the real value of 10k resistance with a multimeter! The 10% tollerance changes the value of about ± 1° C!. In my example I use 9840 Ω instead of 10000 Ω
  • I use a arithmetic mean over 12 readings (2 minutes) in order to normalize the temperature value and discard read errors
  • I use a simple “is_valid_value” function that discard a macroscopic read error. A “digital” read error of ± 20 is converted to an error of ± 14° C ! So if the previous valueis too big or too small, discard the current value

Header file – BasicThermistor.h

/*
 * BasicThermistor.h
 *
 * Created on: 07/ago/2013
 * Author: sarbyn
 * Website: http://www.sarbyn.com
 */
#ifndef BASICTHERMISTOR_H_
#define BASICTHERMISTOR_H_

#include &quot;arduPi.h&quot;
#include

/**
 * Based on cooking-hacks NTC thermistor - datasheet available at
 * http://www.cooking-hacks.com/skin/frontend/default/cooking/pdf/159-282-86001.pdf
 */

// The real 10k resistor value
#define TENKRESISTOR 9840.0f
// Thermistor beta value (from datasheet)
#define BETA 3950.0f
// The thermistor value at room temp (25 C)
// the original value was 2800 ohm
#define THERMISTOR 2700.0f
// The room temperature (25 C) in kelvin
#define ROOMTEMPK 298.15f

// Number of readings over which calculate
// the temperature
#define READINGS 12
// Delay (in ms) between Wire operations
#define DELAY_BETWEEN_OPERATION 20

// The digital value readed from ADC
// must be lower than DIGITAL_TOLLERANCE
// Otherwise it is treaded as a read error
#define DIGITAL_TOLLERANCE 20
// If the digital value readed from ADC is wrong for
// more than DIGITAL_TOLLERANCE_COUNTER, it is a correct value
// and so use it. This is used in case of sudden
// temperature change. If the temperature changes suddenly,
// the value is discarded for DIGITAL_TOLLERANCE_COUNTER reads. After that
// the value is accepted
#define DIGITAL_TOLLERANCE_COUNTER 6

#define ADC_I2C_ADDRESS 8

class BasicThermistor {
public:
   BasicThermistor(byte i2c_address, boolean debug_flag);
   float read_temperature();
private:
   byte address;
   boolean debug;
   int digital_value;
   float read_buffer[READINGS];
   unsigned int cached_digital_value;
   float temperature;
   int invalid_read_counter;
   int buffer_pointer;

   int read_digital_value();
   int is_valid_value(int value);
   float calc_temperature(int value);
};

#endif /* BASICTHERMISTOR_H_ */

Class file – BasicThermistor.cpp

/*
 * BasicThermistor.cpp
 *
 * Created on: 07/ago/2013
 * Author: sarbyn
 * Website: http://www.sarbyn.com
 *
 */

/**
 * Based on cooking-hacks NTC thermistor - datasheet available at
 * http://www.cooking-hacks.com/skin/frontend/default/cooking/pdf/159-282-86001.pdf
 */

#include &quot;BasicThermistor.h&quot;

// Costructor
BasicThermistor::BasicThermistor(byte i2c_address, boolean debug_flag) {
  address = i2c_address;
  debug = debug_flag;
  temperature = 0.0;
  cached_digital_value = 0;
  digital_value = 0;
  invalid_read_counter = 0;
  buffer_pointer = 0;

  for (int i = 0; i &lt; READINGS; i++) {
    read_buffer[i] = -1.0f;
  }
}
// Read the digital value from ADC using Wire class
int BasicThermistor::read_digital_value() {
  unsigned char val_0 = 0;
  unsigned char val_1 = 0;
  unsigned int digital_value;
  Wire.beginTransmission(ADC_I2C_ADDRESS);
  Wire.write(address);
  // sleep in order to reduce read error
  delay(DELAY_BETWEEN_OPERATION);
  Wire.requestFrom(ADC_I2C_ADDRESS, 2);
  // sleep in order to reduce read error
  delay(DELAY_BETWEEN_OPERATION);
  val_0 = Wire.read();
  // sleep in order to reduce read error
  delay(DELAY_BETWEEN_OPERATION);
  val_1 = Wire.read();
  // sleep in order to reduce read error
  delay(DELAY_BETWEEN_OPERATION);
  digital_value = int(val_0)*16 + int(val_1&gt;&gt;4);

  if (debug) {
    printf(&quot;[BT] val [%2x,%2x]\n&quot;, val_0, val_1);
    printf(&quot;[BT] Read digital value %d\n&quot;, digital_value);
  }
  return digital_value;
}

// Check if the readed value is valid
int BasicThermistor::is_valid_value(int value) {
  if (cached_digital_value == 0) {
    cached_digital_value = value;
    return 1;
  }

  // check against DIGITAL_TOLLERANCE
  if (abs(cached_digital_value - value) &lt; DIGITAL_TOLLERANCE) {
    if (debug) printf(&quot;[BT] Valid digital value %d\n&quot;, value);
    cached_digital_value = value;
    invalid_read_counter = 0;
    return 1;
  }
  if (invalid_read_counter &gt; DIGITAL_TOLLERANCE_COUNTER) {
    // too many invalid readings ---&gt; this is a valid read
   if (debug) printf(&quot;[BT] Too many invalid digital value %d..so use it\n&quot;, value);
   cached_digital_value = value;
   invalid_read_counter = 0;
   return 1;
 }

  // throw away invalid reading
  invalid_read_counter++;
  if (debug) printf(&quot;[BT] Invalid digital value %d\n&quot;, value);
  return 0;
}

// Convert the ADC value to Celsius Temperature
float BasicThermistor::calc_temperature(int value) {
  // convert value
  float analog_value = value * 1023.0 / 4095.0;

  analog_value = (1023 / analog_value) - 1;
  analog_value = TENKRESISTOR / analog_value;
  analog_value = analog_value / THERMISTOR;

  if (debug) printf(&quot;[BT] Analog value %f\n&quot;, analog_value);

  float kelvin = log(analog_value);
  kelvin /= BETA;
  kelvin += 1.0 / ROOMTEMPK;
  kelvin = 1.0 / kelvin;

  return kelvin - 273.15;
}

// Main read function: read the current temperature and return it.
// This is designed for a read every 10 seconds: it collects 12 readings
// (READINGS macro value, 2 minutes) and calculate mean over all the values.
// In this way the temperature value does not change suddenly and
// become more stable
float BasicThermistor::read_temperature() {
  digital_value = read_digital_value();
  float single_temperature;
  if (is_valid_value(digital_value)) {
    single_temperature = calc_temperature(digital_value);
    if (debug) printf(&quot;[BT] Single current temperature is %f\n&quot;, single_temperature);
  } else {
    single_temperature = calc_temperature(cached_digital_value);
    if (debug) printf(&quot;[BT] Invalid temp, using cached value %f\n&quot;, single_temperature);
  }

  if (debug)
    printf(&quot;[BT] Storing the temp at pointer %d\n&quot;, buffer_pointer);

  read_buffer[buffer_pointer] = single_temperature;
  buffer_pointer++;

  if (read_buffer[buffer_pointer] == -1.0f) {
    // this is the first reading....init the buffer
    for (int i = buffer_pointer; i &lt; READINGS; i++) {
      read_buffer[i] = single_temperature;
    }
  }

  // reset the pointer
  if (buffer_pointer == READINGS) buffer_pointer = 0;

  temperature = 0;

  if (debug) {
    printf(&quot;[BT] Temp. buffer[&quot;);
    for (int i = 0; i &lt; READINGS; i++) {
      printf(&quot;%0.1f,&quot;, read_buffer[i]);
    }
    printf(&quot;]\n&quot;);
  }

  for (int i = 0; i &lt; READINGS; i++) {
    temperature += read_buffer[i];
  }

  temperature /= READINGS;

  return temperature;
}
 

A $9 arduino board

Some days ago I found on indiegogo.com this campaign:

$9 ARDUINO Compatible STARTER KIT

The goal of the founder is to reach 12.000$ and start the production of the Arduino-like board, and now the campain is over 73.000$! . With 12$ (9$ + shipping), or about 9€, you can start to play with Arduino and electronics. I’ve never tried Arduino boards and yesterday I decided to bought one starter kit from indiegogo.com, so in September my little Raspberry Pi will have a new little friend 🙂

 

LiquidCrystal_i2c for ArduPi

I bought on ebay a simple LCD screen with an i2c controller. My purpose is to add a simple output screen to my project TermoPi (a smart thermostat for my home). I found a ready-to-use CPP library called LiquidCrystal_I2C that helps the developer to connect the LCD screen to an Arduino board. I want to use my raspberry Pi with the coocking-hacks.com “Raspberry to arduino shields” , a connection board that export the arduino input-output pins, using the arduino conventions. A developer can use the Arduino coding style and libraries with his RaspberryPi, using ArduPi CPP library and coocking-hacks shield. But the original LiquidCrystal_I2C library is not compatible with ArduPi compatibility library: this library is similiar to arduino SDK…but it’s not arduino SDK:

  • LiquidCrystal_I2C refers to Arduino “print.cpp” functions, not available on ArduPI
  • ArduPi Wire CPP class implements a different Wire.endTrasmission() function, that close and release the I2C comunication pins (it seems a bug)

After some little changes, LiquidCrystal_I2C is ready to use on RaspberryPi with ArduPI library. You can download the library sources from my Bitbuchet GitHub repository:

https://github.com/sarbyn/liquidcrystal_i2c-for-ardupi