0 Replies Latest reply on Apr 15, 2016 2:23 PM by Squarefox

    [Project][Galileo] Webbot for showing IndieDB stats

    Squarefox

      Hi,

       

      I just finished my project for the Intel Galileo: a webbot, which shows the current statistics of an IndieDB (http://www.indiedb.com/) project.

       

      General description:

      The webbot loads IndieDB project sites every few seconds.

      Then it parses the received HTML data and shows the website hits on the connected LCD display.

      A multicolor LED is used to show the current status (e.g. shines blue, when data is parsed).

      When a hitcounter has increased, a laser is activated to show that.

      You can reset the laser by pressing button 5.

      Button 1 is to show the current hitcounters.

      Button 2 is to show the onboard temperatures of the Galileo.

       

      Hardware:

      • Intel Galileo Gen 1
      • SainSmart LCD shield
      • multicolor LED
      • Laser module
      • Cables

       

      The multicolor LED and the laser are connected to pin 11-13 (LED is 12+13, laser is 11) via ICSP port of the LCD display.

      I soldered 2 cables together to use the ground connector of the port for both, the LED and the laser.


      Software:


      Here is the code:

      // include the library code:
      #include <LiquidCrystal.h>
      #include <math.h>
      #define NO_KEY 0
      #define UP_KEY 3
      #define DOWN_KEY 4
      #define LEFT_KEY 2
      #define RIGHT_KEY 5
      #define SELECT_KEY 1
      // initialize the library with the numbers of the interface pins
      LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
      int hitsMainLast = -1;
      int hitsDemoLast = -1;
      int hitsVideoLast = -1;
      int mode = 0;
      void setup() {
        // set up the LCD's number of columns and rows: 
        lcd.begin(16, 2);
        pinMode(11, OUTPUT);
        pinMode(12, OUTPUT);
        pinMode(13, OUTPUT);
        digitalWrite(11, LOW);
        digitalWrite(12, LOW);
        digitalWrite(13, LOW);
      }
      void loop() {
        // read values
        int value1 = getQuarkTemp();
        int value2 = getADCTemp();
        int key = getKey();
        // change mode
        switch (key)
        {
        case 1:
          mode = 0;
          break;
        case 2:
          mode = 1;
          break;
        case 3:
          break;
        case 4:
          break;
        case 5:
          digitalWrite(11, LOW);
          break;
        }
        // get data from the internet
        int hitsMain = GetHits("curl http://www.indiedb.com/games/nightork-adventures-beyond-the-moons-of-shadalee", "stats", 72, 77);
        delay(500);
        int hitsDemo = GetHits("curl http://www.indiedb.com/games/nightork-adventures-beyond-the-moons-of-shadalee/downloads/nightork-adventures-btmos-demo", "Statistics", 163, 173);
        delay(500);
        int hitsVideo = GetHits("curl http://www.indiedb.com/games/nightork-adventures-beyond-the-moons-of-shadalee/videos", "Statistics", 178, 188);
        if (hitsMain != hitsMainLast || hitsDemo != hitsDemoLast || hitsVideo != hitsVideoLast)
        {
          digitalWrite(11, HIGH);
        }
        hitsMainLast = hitsMain;
        hitsDemoLast = hitsDemo;
        hitsVideoLast = hitsVideo;
        // display text:
        lcd.clear();
        switch (mode)
        {
        case 0:
          lcd.setCursor(0, 0);
          lcd.print("NA:BMS");
          lcd.setCursor(8, 0);
          lcd.print("M:");
          lcd.setCursor(10, 0);
          lcd.print(hitsMain);
          lcd.setCursor(0, 1);
          lcd.print("D:");
          lcd.setCursor(2, 1);
          lcd.print(hitsDemo);
          lcd.setCursor(8, 1);
          lcd.print("V:");
          lcd.setCursor(10, 1);
          lcd.print(hitsVideo);
          break;
        case 1:
          int qTemp = getQuarkTemp();
          int adcTemp = getADCTemp();
          lcd.setCursor(0, 0);
          lcd.print("Q-T:");
          lcd.setCursor(7, 0);
          lcd.print(qTemp);
          lcd.setCursor(0, 1);
          lcd.print("ADC-T:");
          lcd.setCursor(7, 1);
          lcd.print(adcTemp);
          break;
        }
        delay(2000);
      }
      // ===================================
      // Read Hits
      // ===================================
      int GetHits(const char* url, const char* indicator, int first, int last)
      {
        // create buffer
        char output[1000];
        for (int i=0; i<1000; ++i)
          output[i] = 0;
        // fetch
        digitalWrite(12, HIGH);
        FILE* fp = popen(url, "r");
        digitalWrite(12, LOW);
        if (fp == NULL) 
          return -1;
        // parse
        digitalWrite(13, HIGH);
        int result = 0;
        while (fgets(output, sizeof(output), fp) != NULL)
        {
          String str = output;
          if (str.substring(first, last) == indicator)
          {
            int cur = str.indexOf('>') + 1;
            while (output[cur] != ' ')
            {
              result = result * 10 + (output[cur] - '0');
              ++cur;    
            }
            break;
          }
        }
        digitalWrite(13, LOW);
        if (pclose(fp) != 0)
          return -1;
        return result;
      }
      // ===================================
      // Read Key
      // ===================================
      static int DEFAULT_KEY_PIN = 0; 
      static int DEFAULT_THRESHOLD = 100;
      static int UPKEY_ARV = 144; //that's read "analogue read value"
      static int DOWNKEY_ARV = 329;
      static int LEFTKEY_ARV = 505;
      static int RIGHTKEY_ARV = 0;
      static int SELKEY_ARV = 742;
      static int NOKEY_ARV = 1023;
      int getKey()
      {
        int curInput = analogRead(DEFAULT_KEY_PIN);
        if (curInput > UPKEY_ARV - DEFAULT_THRESHOLD && curInput < UPKEY_ARV + DEFAULT_THRESHOLD ) return UP_KEY;
        else if (curInput > DOWNKEY_ARV - DEFAULT_THRESHOLD && curInput < DOWNKEY_ARV + DEFAULT_THRESHOLD ) return DOWN_KEY;
        else if (curInput > RIGHTKEY_ARV - DEFAULT_THRESHOLD && curInput < RIGHTKEY_ARV + DEFAULT_THRESHOLD ) return RIGHT_KEY;
        else if (curInput > LEFTKEY_ARV - DEFAULT_THRESHOLD && curInput < LEFTKEY_ARV + DEFAULT_THRESHOLD ) return LEFT_KEY;
        else if (curInput > SELKEY_ARV - DEFAULT_THRESHOLD && curInput < SELKEY_ARV + DEFAULT_THRESHOLD ) return SELECT_KEY;
        else return NO_KEY;  
      }
      // ===================================
      // Quark Temperature
      // ===================================
      char temp_raw[6];
      int getQuarkTemp() {
        FILE *fp;
        fp = fopen("/sys/class/thermal/thermal_zone0/temp", "r"); 
        fgets(temp_raw, 5, fp);
        fclose(fp);
        int temp = atoi(temp_raw);
        temp /= 100;
        return temp;  
      }
      char scale[4];
      char raw[4];
      char offset[4];
      int raw_i;
      int scale_i;
      int offset_i;
      
      int getADCTemp() {
        FILE *fp_raw;
        fp_raw = fopen("/sys/bus/iio/devices/iio:device0/in_temp0_raw", "r");     //read the values from scale, raw and offset files.
        fgets(raw, 4, fp_raw);                                                    //we need all three values, because the formula for
        fclose(fp_raw);                                                           //calulating the actual temperature in milli-degrees Celcius
        //is: TEMP = (RAW + OFFSET) * SCALE 
        FILE *fp_scale;
        fp_scale = fopen("/sys/bus/iio/devices/iio:device0/in_temp0_scale", "r");
        fgets(scale, 4, fp_scale);
        fclose(fp_scale);
        FILE *fp_offset;
        fp_offset = fopen("/sys/bus/iio/devices/iio:device0/in_temp0_offset", "r");
        fgets(offset, 4, fp_offset);
        fclose(fp_offset);
        raw_i = atoi(raw);         //we have the values now, but they are in ASCII form-                                                       
        scale_i = atoi(scale);     //we need them as integers so we can use them for calculations.
        offset_i = atoi(offset);
        int temp = (raw_i + offset_i) * scale_i;  //Calculate temperature in milli-degrees celcius
        temp /= 1000;                         //divide by 1000 to convert to degrees celcius
        return temp;  
      }
      
      
      
      
      
      

       

       

      As you can see, the IndieDB project I used is "Nightork Adventures" (http://www.indiedb.com/games/nightork-adventures-beyond-the-moons-of-shadalee),

      which is a game I made in the last two years. Feel free to visit the site and keep my laser burning .

       

      Here is a photo of the completed webbot:

      IndieDbBot.jpg

       

      Kind regards,

      Squarefox