Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

Netduino Plus Physical Gmail Notifier


  • Please log in to reply
10 replies to this topic

#1 smarcus3

smarcus3

    Advanced Member

  • Members
  • PipPipPip
  • 134 posts

Posted 09 April 2012 - 07:32 PM

I am going to be building a project which notifiers the user by raising a flag when a gmail message is found.

First I needed to create a php website that displays the number of unread messages for me. The site is located here: MY SITE The reason you need a site to host this is that the netduino plus doesn't handle ssl which the majority of email providers such as google require. The site is a middle man. This solution is nicer than running your own server / program on another computer because you do not depend on this additional computer.

The website give you a string like this which can be read by the netduino using a function while will be talked about in the next post.

Posted Image

Here is the php code for anyone who needs it.

<head>

<title></title>

</head>

	<body>

<?php

$mbox = imap_open ("{imap.gmail.com:993/imap/ssl}INBOX", "*******@gmail.com","******", OP_READONLY) or die ("can't connect: " . imap_last_error());

$status = imap_status($mbox, "{imap.gmail.com}INBOX", SA_ALL);

if ($status) {
  echo "Messages:   " . $status->messages    . "<br />\n";
  echo "Recent:     " . $status->recent      . "<br />\n";
  echo "Unseen:     " . $status->unseen      . "<br />\n";
  echo "UIDnext:    " . $status->uidnext     . "<br />\n";
  echo "UIDvalidity:" . $status->uidvalidity . "<br />\n";
} else {
  echo "imap_status failed: " . imap_last_error() . "\n";
}


?>

	</body>

</html>

I will be posting in the future the c# code that runs on the micro-controller. Stay tuned and feel free to ask questions.
Steve


My Other Hobby: Engineer Turned Baker

#2 smarcus3

smarcus3

    Advanced Member

  • Members
  • PipPipPip
  • 134 posts

Posted 09 April 2012 - 08:47 PM

Here is the c# code which holds 2 of my miscellaneous functions.

using System;
using Microsoft.SPOT;
using System.Net;
using System.IO;
using System.Text;
using Toolbox.NETMF;

namespace EmailStockChecker
{
    public static class clMisc
    {
        public static string GetStringInBetween(string strBegin, string strEnd, string strSource)
        {
            string result = "";
            int iIndexOfBegin = strSource.IndexOf(strBegin);
            if (iIndexOfBegin != -1)
            {
                strSource = strSource.Substring(iIndexOfBegin
                    + strBegin.Length);
                int iEnd = strSource.IndexOf(strEnd);
                if (iEnd != -1)
                { 
                    result = strSource.Substring(0, iEnd);
                }
            }
            else
                // stay where we are
                result = strSource;

            return result;
        }

        public static string GetOnlineWebPage(string url)
        {
            // used to build entire input
            StringBuilder sb = new StringBuilder();

            // used on each read operation
            byte[] buf = new byte[8192];

            // prepare the web page we will be asking for
            HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url);

            // execute the request
            HttpWebResponse response = (HttpWebResponse)
                request.GetResponse();

            // we will read data via the response stream
            Stream resStream = response.GetResponseStream();

            string tempString = null;
            int count = 0;
            
            do
            {
                // fill the buffer with data
                count = resStream.Read(buf, 0, buf.Length);

                // make sure we read some data
                if (count != 0)
                {
                    // translate from bytes to ASCII text
                    //tempString = Encoding.ASCII.GetString //(buf, 0, count);
                    tempString = new string(Tools.Bytes2Chars(buf));

                    // continue building the string
                    sb.Append(tempString);
                }
            }
            while (count > 0); // any more data to read?

            return sb.ToString();
        }
    }
}

The getStringInBetween function returns a string between 2 user inputted strings. This is useful in conjunction with the second function. getOnlineWebPage function returns a page as a string.

The second function allows netduino to pull data from an html page such as http://smarcus3.x10.mx/ and return it as a string. The first function allows you to basically parse up this data into useful chunks.
Steve


My Other Hobby: Engineer Turned Baker

#3 smarcus3

smarcus3

    Advanced Member

  • Members
  • PipPipPip
  • 134 posts

Posted 12 April 2012 - 08:46 PM

My project is almost completely together. There is a LCD which displays stock data on it and a servo which raises based on if there is an unread email message or not. Here are 3 pictures which show the arm raising, kinda. The pictures also show the stock data which is formatted like this.

TICKER Current Price
Change Percent Change
Daily Change
Total Value

Posted Image

Posted Image

Posted Image
Steve


My Other Hobby: Engineer Turned Baker

#4 Stefan

Stefan

    Moderator

  • Members
  • PipPipPip
  • 1965 posts
  • LocationBreda, the Netherlands

Posted 12 April 2012 - 08:47 PM

I really, really, REALLY like your box :D
"Fact that I'm a moderator doesn't make me an expert in things." Stefan, the eternal newb!
My .NETMF projects: .NETMF Toolbox / Gadgeteer Light / Some PCB designs

#5 smarcus3

smarcus3

    Advanced Member

  • Members
  • PipPipPip
  • 134 posts

Posted 12 April 2012 - 08:48 PM

I really, really, REALLY like your box :D


Why buy enclosures when spark fun gives you nice little red boxes.
Steve


My Other Hobby: Engineer Turned Baker

#6 smarcus3

smarcus3

    Advanced Member

  • Members
  • PipPipPip
  • 134 posts

Posted 12 April 2012 - 08:52 PM

Below is all of my code. If anyone would like an explanation on how something works just let me know and I can explain any part.

Program.cs

using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.NetduinoPlus;
using FusionWare.SPOT.Hardware;
using MicroLiquidCrystal;
using System.Diagnostics;
using Servo_API;
 


namespace EmailStockChecker
{
    public class Program
    {
        public static void Main()
        {
            //LCD SECCTION

            // initialize i2c bus (only one instance is allowed)
            var bus = new I2CBus();

            // initialize provider (multiple devices can be attached to same bus)
            var lcdProvider = new MCP23008LcdTransferProvider(bus);

            // create the LCD interface
            var lcd = new Lcd(lcdProvider);

            // set up the LCD's number of columns and rows: 
            lcd.Begin(20, 4);

            lcd.BlinkCursor = false;

            // Print a message to the LCD.
            lcd.Clear();
            lcd.Write("STARTING UP ... ");
            lcd.SetCursorPosition(0, 2);
            lcd.Write("PLEASE WAIT ... ");

            //Stopwatch sw = Stopwatch.StartNew();

            //END OF LCD SECTION
            
            
            //Variable Decleration
            //DECLARE ALL STOCKS

            //int numberOfStocks = 6;
            int currentStockOnLCD = 1;

            clFinance stockEEM = new clFinance("EEM", 100);
            clFinance stockEFA = new clFinance("EFA", 100);
            clFinance stockIJJ = new clFinance("IJJ", 200);
            clFinance stockIVV = new clFinance("IVV", 200);
            clFinance stockIJK = new clFinance("IJK", 123);
            clFinance stockVT = new clFinance("VT", 456);
            
            int unreadEmailCount = 0;
            
            Stopwatch StopWatchEmailChecker = Stopwatch.StartNew();
            //Stopwatch StopWatchStockChecker = Stopwatch.StartNew();
            Stopwatch StopWatchLCDChange = Stopwatch.StartNew();

            Boolean BlinkLEDs = false;
            int BlinkerCounter = 0;
            //Declare Servo
            Servo servo = new Servo(Pins.GPIO_PIN_D9);
            
            //Brings the servo home.
            servo.Degree = 0;

            bool isServoDown = true;

            //VARIABLE DECLERATION
            //const int SDA = 10; //Analog Pin 4
            //const int SCL = 11; //Analog Pin 5
            
            //LED SECTION

            //Already Hooked with On Board
            OutputPort onBoardLED = new OutputPort(Pins.ONBOARD_LED, false);
            OutputPort LED1 = new OutputPort(Pins.GPIO_PIN_D2, false);
            OutputPort LED2 = new OutputPort(Pins.GPIO_PIN_D3, false);
            OutputPort LED3 = new OutputPort(Pins.GPIO_PIN_D4, false);
            OutputPort LED4 = new OutputPort(Pins.GPIO_PIN_D5, false);

            //END OF LED SECTION


            //Continuous Loop for the microcontroller
            while (true)
            {
                
                //Email Checker
                if (StopWatchEmailChecker.ElapsedMilliseconds > clConstants.EMAILUPDATETIME * 1000)
                {
                    unreadEmailCount = clEmail.GetUnreadEmailCount("http://smarcus3.x10.mx");

                    if (unreadEmailCount > 0)
                    {
                        //You have a message

                        //Raise Flag
                        if (isServoDown == true)
                        {
                            for (int i = 0; i <= 180; i++)
                            {
                                servo.Degree = i;
                                Thread.Sleep(50);
                            }

                            Thread.Sleep(1000);
                        }
                        //Blink LEDS
                        BlinkLEDs = true;
                    }
                    else
                    {
                        //No messages

                        //Lower Flag
                        if (isServoDown == false)
                        {
                            for (int i = 180; i >= 0; i--)
                            {
                                servo.Degree = i;
                                Thread.Sleep(50);
                            }
                            Thread.Sleep(1000);
                        }
                       
                        //Stop LEDS
                        BlinkLEDs = false;
                    }
                    StopWatchEmailChecker.Stop();
                    StopWatchEmailChecker.Reset();
                    StopWatchEmailChecker.Start();
                }

                //LCD SECTION

                if (StopWatchLCDChange.ElapsedMilliseconds >= 1000 * clConstants.STOCKUPDATETIME) //every 60 seconds
                {
                    

                    switch (currentStockOnLCD)
                    {
                        case 1:
                            currentStockOnLCD += 1;
                            stockEEM.UpdateStock();
                            clMisc.updateLCDDisplay(stockEEM, lcd);
                            break;
                        case 2:
                            currentStockOnLCD += 1;
                            stockEFA.UpdateStock();
                            clMisc.updateLCDDisplay(stockEFA, lcd);
                            break;
                        case 3:
                            currentStockOnLCD += 1;
                            stockIJJ.UpdateStock();
                            clMisc.updateLCDDisplay(stockIJJ, lcd);
                            break;
                        case 4:
                            currentStockOnLCD += 1;
                            stockIJK.UpdateStock();
                            clMisc.updateLCDDisplay(stockIJK, lcd);
                            break;
                        case 5:
                            currentStockOnLCD += 1;
                            stockIVV.UpdateStock();
                            clMisc.updateLCDDisplay(stockIVV, lcd);
                            break;
                        case 6:
                            currentStockOnLCD = 1;
                            stockVT.UpdateStock();
                            clMisc.updateLCDDisplay(stockVT, lcd);
                            break;
                    }

                    StopWatchLCDChange.Stop();
                    StopWatchLCDChange.Reset();
                    StopWatchLCDChange.Start();
                    
                }

                //END OF LCD SECTION

                //LED SECTION

                if (BlinkLEDs)
                {
                    //Blinks half of the LEDs at a time. 
                    if (BlinkerCounter == 0)
                    {
                        clMisc.ToggleDigitalPins(LED1);
                        clMisc.ToggleDigitalPins(LED2);
                        BlinkerCounter = 1;
                    }
                    else
                    {
                        clMisc.ToggleDigitalPins(LED3);
                        clMisc.ToggleDigitalPins(LED4);
                        BlinkerCounter = 0;
                    }
                }
                else
                {
                    LED1.Write(false);
                    LED2.Write(false);
                    LED3.Write(false);
                    LED4.Write(false);
                }

                    //LED SECTION

                //Blinks the onboard LED
                clMisc.ToggleDigitalPins(onBoardLED);
                
                //adds a pause in the controllers thread
                Thread.Sleep(100);
            }
        }

    }
    
}

clMisc.cs

using System;
//using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using System.Net;
using System.IO;
using System.Text;
using Toolbox.NETMF;
using MicroLiquidCrystal;
using System.Threading;


namespace EmailStockChecker
{
    public static class clMisc
    {
        public static string removeIllegalCharacters(string inputString)
        {
            int asciiValue;
            for (int i = 0; i < inputString.Length - 1; i++)
            {
                asciiValue = (int) inputString[i];

                if (asciiValue == 45 || asciiValue == 36 || asciiValue == 46 || asciiValue == 37 || (asciiValue >= 48 && asciiValue <= 57) ||
                    (asciiValue >= 97 && asciiValue <= 122) || (asciiValue >= 65 && asciiValue <= 90) || asciiValue == 32 || asciiValue == 44)
                {
                    //This character is fine.
                    //Move on to the next
                }
                else
                {
                    return "ILLEGAL CHAR FOUND";
                }
            }
            return inputString;
        }
        
        public static string setDecimalPlaceOfString(double number, int decimalPlaces, bool placeCommas)
        {
            /* THIS FUNCTION TAKES IN A DOUBLE AND RETURNS IT IN A STRING WITH A SPECIFIED NUMBER OF DECIMAL 
             * PLACES WITH OR WITHOUT COMMAS. 
             * 
             * INPUT:   NUMBER          ---> DOUBLE WHICH CONTAINS THE UNFORMATTED NUMBER
             *          DECIMALPLACES   ---> INTEGER WHICH CONTAINS THE NUMBER OF WANTED DECIMALPLACES
             *          PLACECOMMAS     ---> BOOL WHEN TRUE COMMAS ARE INSERTED INTO THE OUTPUTTED STRING
             * 
             * OUTPUT: A STRING WHICH HAS THE APPROPRIATE NUMBER OF DECIMAL PLACES WITH COMMAS IF REQUESTED.
             */
            string tempstr = "";
            //This path is for doubles which already have a decimal place. adds commas as needed to the string
            if (number.ToString().IndexOf('.') >= 0)
            {
                if (number.ToString().Length - number.ToString().IndexOf('.') - 1 >= decimalPlaces)
                    tempstr = number.ToString().Substring(0, number.ToString().IndexOf('.') + decimalPlaces + 1);
                else
                {
                    tempstr = number.ToString();
                    for (int i = number.ToString().Length - 1; i < number.ToString().IndexOf('.') + decimalPlaces; i++)
                    {

                        tempstr += "0";

                    }
                }

                if (placeCommas == true)
                {
                    for (int i = tempstr.Length - 6; i > 0; i = i - 3)
                    {
                        tempstr = tempstr.Substring(0, i) + "," + tempstr.Substring(i, tempstr.Length - i);

                    }
                }
                return tempstr; //return number.ToString().Substring(0, number.ToString().IndexOf('.') + decimalPlaces + 1);
            }
            //If there isn't a deciaml in the number
            else
            {
                string tempString = "";
                for (int i = 0; i < decimalPlaces; i++)
                {
                    if (i == 0)
                        tempString = ".";
                    tempString += "0";

                }
                tempString = number.ToString() + tempString;

                //adds commas as needed to the string
                if (tempString.IndexOf('.') >= 0 && placeCommas == true)
                {
                    for (int i = tempString.Length - 6; i > 0; i = i - 3)
                    {
                        tempString = tempString.Substring(0, i) + "," + tempString.Substring(i, tempString.Length - i);

                    }
                }
                return tempString;
            }
        }
        public static string setDecimalPlaceOfString(int number, int decimalPlaces, bool placeCommas)
        {
            /* THIS FUNCTION TAKES IN A INTEGER AND RETURNS IT IN A STRING WITH A SPECIFIED NUMBER OF DECIMAL 
             * PLACES WITH OR WITHOUT COMMAS. 
             * 
             * INPUT:   NUMBER          ---> INTEGER WHICH CONTAINS THE UNFORMATTED NUMBER
             *          DECIMALPLACES   ---> INTEGER WHICH CONTAINS THE NUMBER OF WANTED DECIMALPLACES
             *          PLACECOMMAS     ---> BOOL WHEN TRUE COMMAS ARE INSERTED INTO THE OUTPUTTED STRING
             * 
             * OUTPUT: A STRING WHICH HAS THE APPROPRIATE NUMBER OF DECIMAL PLACES WITH COMMAS IF REQUESTED.
             */
            string tempstr = number.ToString().Substring(0, number.ToString().IndexOf('.') + decimalPlaces + 1);

            //This path is for doubles which already have a decimal place. adds commas as needed to the string
            if (number.ToString().IndexOf('.') >= 0 && placeCommas == true)
            {
                for (int i = tempstr.Length - 6; i > 0; i = i - 3)
                {
                    tempstr = tempstr.Substring(0, i) + "," + tempstr.Substring(i, tempstr.Length - i);

                }
                return tempstr; //return number.ToString().Substring(0, number.ToString().IndexOf('.') + decimalPlaces + 1);
            }
            //If there isn't a deciaml in the number
            else
            {
                string tempString = "";
                for (int i = 0; i < decimalPlaces; i++)
                {
                    if (i == 0)
                        tempString = ".";
                    tempString += "0";

                }
                tempString = number.ToString() + tempString;

                //adds commas as needed to the string
                if (tempString.IndexOf('.') >= 0 && placeCommas == true)
                {
                    for (int i = tempString.Length - 6; i > 0; i = i - 3)
                    {
                        tempString = tempString.Substring(0, i) + "," + tempString.Substring(i, tempString.Length - i);

                    }
                }
                return tempString;
            }
        }
        public static string centerString(string sourceString1, string sourceString2, int formattedStringLength)
        {
            /*THIS FUNCTION TAKES IN TWO STRINGS AND CENTERS IT IN THE OUTPUTTED STRING. THIS RETURNED STRING'S 
             * LENGTH IS DETERMINED BY THE INTEGER, FORMATTEDSTRINGLENGTH.
             * 
             * INPUTS:  SOURCESTRING1           ---> STRING CONTAINING A STRING NEEDED TO BE CENTERED
             *          SOURCESTRING2           ---> STRING CONTAINING A STRING NEEDED TO BE CENTERED
             *          FORMATTEDSTRINGLENGTH   ---> INTEGER SPECIFING THE LENGTH OF THE RETURNED STRING
             * 
             * OUTPUT:  A STRING THE LENGTH OF FORMATTEDSTRINGLEGTH THAT CENTERS THE SOURCESTRINGS
             */ 
            string formattedString = "";

            if (sourceString1.Length + sourceString2.Length < formattedStringLength)
            {
                int diference = (int) (formattedStringLength - sourceString1.Length -  sourceString2.Length)/3;

                //only 2 spaces
                if (diference == 0 && formattedStringLength - sourceString1.Length - sourceString2.Length >= 2)
                {
                    diference = 1;
                }

                //only 1 space
                if (diference == 0 && formattedStringLength - sourceString1.Length - sourceString2.Length == 1)
                    return sourceString1 + " " + sourceString2;
                
                for (int i = 0; i < formattedStringLength; i++)
                {
                    if (i < diference)
                        formattedString = formattedString + " ";
                    else if (i < sourceString1.Length + diference)
                    {
                        formattedString = formattedString + sourceString1;
                        i = diference + sourceString1.Length - 1;
                    }
                    else if (i < sourceString1.Length + 2 * diference)
                    {
                        formattedString = formattedString + " ";
                    }
                    else if (i < sourceString1.Length + sourceString2.Length + 2 * diference)
                    {
                        formattedString = formattedString + sourceString2;
                        i = sourceString1.Length + sourceString2.Length + 2 * diference - 1;
                    }
                    else
                        formattedString = formattedString + " ";
                }

                return formattedString;
            }
            else
                return sourceString1 + sourceString2;
        }
        public static string centerString(string sourceString, int formattedStringLength)
        {
            /*THIS FUNCTION TAKES IN ONE STRINGS AND CENTERS IT IN THE OUTPUTTED STRING. THIS RETURNED STRING'S 
             * LENGTH IS DETERMINED BY THE INTEGER, FORMATTEDSTRINGLENGTH.
             * 
             * INPUTS:  SOURCESTRING1           ---> STRING CONTAINING A STRING NEEDED TO BE CENTERED
             *          FORMATTEDSTRINGLENGTH   ---> INTEGER SPECIFING THE LENGTH OF THE RETURNED STRING
             * 
             * OUTPUT:  A STRING THE LENGTH OF FORMATTEDSTRINGLEGTH THAT CENTERS THE SOURCESTRING
             */ 
            string formattedString = "";

            if (sourceString.Length < formattedStringLength)
            {
                int diference = formattedStringLength - sourceString.Length;
                for (int i = 0; i < formattedStringLength; i++)
                {
                    if (i < (int) diference/2)
                        formattedString = formattedString + " ";
                    else if (i < sourceString.Length + (int) diference/2)
                    {
                        formattedString = formattedString + sourceString;
                        i = (int)diference / 2 + sourceString.Length - 1;
                    }
                    else
                        formattedString = formattedString + " ";
                }

                return formattedString = formattedString.Substring(0,formattedStringLength);
            }
            else
                //forces it to be the right length
                return sourceString.Substring(0, formattedStringLength);
        }
        public static void updateLCDDisplay(clFinance Stock, Lcd lcd) //needs LCD in it
        {
            /* THIS IS A HELPER FUNCTION WHICH IS CALLED TO UPDATE THE DISPLAY OF THE LCD DISPLAY WITH THE 
             * INPUTTED STOCK. THIS FUNCTION KEEPS THE MAIN FUNCTION CLEAN.
             * 
             *                  //     LCD Display     //
             *
             *                  //        LAYOUT       // 
             *                  //  STOCK NAME   LAST  //
             *                  //    CHANGE PERCENT   //
             *                  //   DAILY  -  CHANGE  //
             *                  //    MARKET VALUE     //
             * 
             */ 
            
            //20 x 4 size LCD

            

            string formattedStockName = "";
            string formattedMarketValue = "";
            string formattedDailyChange = "";
            string formattedChange = "";
            string formattedPercChange = "";
            string formattedLast = "";


            //Stock Name
            //if (Stock.GetStockName().Length > 20)
                formattedStockName = Stock.GetTicker();
            //else
            //    formattedStockName = Stock.GetStockName();

            //Change
            if (Stock.GetChange() > 0)
                formattedChange = "$" + setDecimalPlaceOfString(Stock.GetChange(), 2, true);
            else
                formattedChange = "-$" + setDecimalPlaceOfString(Stock.GetChange() * -1,2, true);
            
            //Percent
            formattedPercChange = setDecimalPlaceOfString(Stock.GetPercentChange(), 2, true) +"%";

            //Daily Change
            if (Stock.GetDailyChange() > 0)
                formattedDailyChange = "$" + setDecimalPlaceOfString(Stock.GetDailyChange(),2, true);
            else
                formattedDailyChange = "-$" + setDecimalPlaceOfString(Stock.GetDailyChange() * -1, 2, true);
            
            //Market Value
            if (Stock.GetMarketValue() > 0)
                formattedMarketValue = "$" + setDecimalPlaceOfString(Stock.GetMarketValue(), 2,true);
            else
                formattedMarketValue = "-$" + setDecimalPlaceOfString(Stock.GetMarketValue() * -1, 2,true);

            //Last
            formattedLast = "$" + setDecimalPlaceOfString(Stock.GetLastPrice(), 2, true);

            lcd.Clear();
            //lcd.SetCursorPosition(0, 0);
            Thread.Sleep(clConstants.DELAYBETWEENLCDWRITEMS);

            //Row 1
            clMisc.wrtieCharbyCharLCD(lcd, removeIllegalCharacters(centerString(formattedStockName, formattedLast, 20)), 0);

            //Row 2
            clMisc.wrtieCharbyCharLCD(lcd, removeIllegalCharacters(centerString(formattedChange, formattedPercChange, 20)), 1);

            //Row 3
            clMisc.wrtieCharbyCharLCD(lcd, removeIllegalCharacters(centerString(formattedDailyChange, 20)), 2);

            //Row 4

            clMisc.wrtieCharbyCharLCD(lcd, removeIllegalCharacters(centerString(formattedMarketValue, 20)), 3);
            //TESTING CODE
            
            //string temp2 = center2String(formattedStockName,formattedLast, 20);
            //string temp3 = center2String(formattedChange, formattedPercChange, 20);
            //string temp1 = center1String(formattedDailyChange, 20);
            //string temp = center1String(formattedMarketValue, 20);

        }
        public static void wrtieCharbyCharLCD(Lcd lcd, string inputString, int cursorStartRow)
        {
            //Needs a string the width of the LCD.

            lcd.SetCursorPosition(0, cursorStartRow); //COLUMN ROW
            for (int i = 0; i < clConstants.LCDWIDTH; i++)
            {
                if (inputString[i].ToString() != " ")
                {
                    Thread.Sleep(clConstants.DELAYBETWEENLCDWRITEMS);
                    lcd.SetCursorPosition(i, cursorStartRow);
                    lcd.Write(inputString[i].ToString());
                }
            }
        }
        public static void ToggleDigitalPins(OutputPort outPort)
        {
            /* THIS FUNCTION TAKES IN A PORT AND SWAPS THE STATE OF THE DIGITAL PIN. THIS MEANS THAT IF A PIN
             * IS HIGH (5V) IT IS SWITCHED TO LOW (0V). THE OPPOSITE IS ALSO TRUE. 
             * 
             * INPUT:   OUTPORT --->    TAKES IN AN OUTPORT PIN WHICH IS GOING TO BE TOGGED TO THE STATE IT IS NOT 
             *                          CURRENTLY IN.
             */
            if (outPort.Read())
                outPort.Write(false);
            else
                outPort.Write(true);
        }
        public static string GetStringInBetween(string strBegin, string strEnd, string strSource)
        {
            /* THIS FUNCTION RETURNS A STRING WHICH IS BETWEEN TWO SPECIFIED STRINGS. THESE TWO SEARCH STRINGS ENCAPSULATE
             * THE TARGET STRING WHICH IS GOING TO BE FOUND. THIS FUNCTION IS VERY USEFUL TO PULL INFORMATION
             * FROM A LONG STRING SUCH AS THE OUTPUT FROM AN ONLINE WEBSITE. THIS USE IS THE REASON WHY THIS FUNCTION WAS
             * WRITTEN FOR THIS EXPLICIT REASON.
             * 
             * INPUTS:  STRBEGIN    --->    THE FIRST STRING THAT MARKS THE BEGINNING OF THE STRING WHICH IS GOING TO BE FOUND
             *          STREND      --->    THE SECOND STRING THAT MARKS THE END OF THE STRING WHICH IS GOING TO BE FOUND
             *          STRSOURCE   --->    THE SOURCE STRING THAT HAS THE STRBEGIN AND STREND IN IT. THIS STRING ALSO HOLDS THE
             *                              TARGET STRING WHICH IS GOING TO BE FOUND.
             *                              
             * OUTPUT:  A STRING WHICH WAS BETWEEN STRBEGIN AND STREND AND CONTAINED IN STRSOURCE
             */
            string result = "";
            int iIndexOfBegin = strSource.IndexOf(strBegin);
            if (iIndexOfBegin != -1)
            {
                strSource = strSource.Substring(iIndexOfBegin+strBegin.Length);
                int iEnd = strSource.IndexOf(strEnd);
                if (iEnd != -1)
                {
                    result = strSource.Substring(0, iEnd);
                }
            }
            else
                // stay where we are
                result = strSource;

            return result;
        }
        public static string GetOnlineWebPage(string url)
        {
            /* THIS FUNCTION GETS ONLINEWEBPAGES AS LONG AS THEY ARE NOT HTTPS. THE NETDUINO AT THIS POINT DOESNT
             * HANDLE DEALING WITH HTTPS PAGES OR SSL. THE WORK AROUND TO THIS IS TO USE AN PHP WEBSITE. THE FUNCITON 
             * RETURNS THE ENTIRE WEBSITE AS A LONG, LONG STRING. ALL OF THE HTML WILL BE RETURNED WITH THIS FUNCTION
             * SUCH AS HEADER AND BODY BREAKS. THIS FUNCTION GOES HAND IN HAND WITH GETSTRINGINBETWEEN
             * 
             * INPUT:   URL     --->    A STRING WHICH CONTAINS THE URL OF THE SITE SUCH AS HTTP://WWW.GMAIL.COM
             * 
             * OUTPUT:  A STRING WHICH CONTAINS ALL THE RAW DATA OF THE WEBSITE
             */ 
            // used to build entire input
            //clStringBuilder sb = new clStringBuilder();

            // used on each read operation
            byte[] buf = new byte[100]; //8192 was the original value but we ran out of memory.
 
            // prepare the web page we will be asking for
            HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url);

            // execute the request
            HttpWebResponse response = (HttpWebResponse)
                request.GetResponse();

            // we will read data via the response stream
            Stream resStream = response.GetResponseStream();

            string tempString = null;
            int count = 0;
            string fullstring = "";
            do
            {
                // fill the buffer with data
                count = resStream.Read(buf, 0, buf.Length);

                // make sure we read some data
                if (count != 0)
                {
                    // translate from bytes to ASCII text
                    //tempString = Encoding.ASCII.GetString //(buf, 0, count);
                    tempString = new string(Tools.Bytes2Chars(buf));

                    // continue building the string
                    fullstring += tempString; //sb.Append(tempString);
                }
            }
            while (count > 0); // any more data to read?

            return fullstring;
        }
        public static string GetOnlineWebPage(string url, int beginnigTrimAmmount, int maxStringLength)
        {
            /* THIS FUNCTION GETS ONLINEWEBPAGES AS LONG AS THEY ARE NOT HTTPS. THE NETDUINO AT THIS POINT DOESNT
             * HANDLE DEALING WITH HTTPS PAGES OR SSL. THE WORK AROUND TO THIS IS TO USE AN PHP WEBSITE. THE FUNCITON 
             * RETURNS THE ENTIRE WEBSITE AS A LONG, LONG STRING. ALL OF THE HTML WILL BE RETURNED WITH THIS FUNCTION
             * SUCH AS HEADER AND BODY BREAKS. THIS FUNCTION GOES HAND IN HAND WITH GETSTRINGINBETWEEN
             * 
             * INPUT:   URL     --->    A STRING WHICH CONTAINS THE URL OF THE SITE SUCH AS HTTP://WWW.GMAIL.COM
             * 
             * OUTPUT:  A STRING WHICH CONTAINS ALL THE RAW DATA OF THE WEBSITE
             */
            // used to build entire input
            //clStringBuilder sb = new clStringBuilder();

            // used on each read operation
            byte[] buf = new byte[25]; //8192 was the original value but we ran out of memory.
            //bool hasItBeenFound = false;
            string fullstring = "";
            //while (hasItBeenFound == false)
            //{
            try
            {

                // prepare the web page we will be asking for
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);

                // execute the request
                HttpWebResponse response = (HttpWebResponse)
                    request.GetResponse();

                // we will read data via the response stream
                Stream resStream = response.GetResponseStream();


                int count = 0;
                    
                bool keepGoing = true;
                bool hasFirstTrimHappened = false;
                bool hasSecondTrimHappened = false;
                do
                {
                    // fill the buffer with data
                    count = resStream.Read(buf, 0, buf.Length);

                    // make sure we read some data
                    if (count != 0)
                    {
                        // translate from bytes to ASCII text
                        //tempString = Encoding.ASCII.GetString //(buf, 0, count);
                        fullstring += new string(Tools.Bytes2Chars(buf));

                        // continue building the string
                        //fullstring += tempString; //sb.Append(tempString);
                    }
                    else
                        keepGoing = false; //Add data has been read

                    //cuts off the worthless front end data
                    if ((hasFirstTrimHappened == false || hasSecondTrimHappened == false) && fullstring.Length > beginnigTrimAmmount / 2)
                    {
                        fullstring = fullstring.Substring(beginnigTrimAmmount / 2);
                        if (hasFirstTrimHappened == false)
                            hasFirstTrimHappened = true;
                        else
                            hasSecondTrimHappened = true;
                    }

                    if (fullstring.Length > maxStringLength && hasFirstTrimHappened == true)
                        keepGoing = false;

                }
                while (keepGoing == true); // any more data to read?

                //fullstring = fullstring.Substring(beginnigTrimAmmount - 1);
                if (maxStringLength < fullstring.Length)
                    fullstring = fullstring.Substring(0, maxStringLength - 1);

                return fullstring;
            }
            catch
            {
                return "BADWEBPAGE";
            }
            }
            //return fullstring;
        //

    }
}

clConstants.cs

using System;
using Microsoft.SPOT;

namespace EmailStockChecker
{
    public static class clConstants
    {
        public const int STOCKUPDATETIME = 2;
        public const int EMAILUPDATETIME = 60;
        public const int DELAYBETWEENLCDWRITEMS = 200;

        public const int LCDWIDTH = 20;
        public const int LCDHEIGHT = 4;
    }
}

clFinance.cs

using System;
using System.Threading;
using System.IO.Ports;
using System.Text;
using System.IO;
using Microsoft.SPOT;
using System.Net;
using SecretLabs.NETMF.Hardware.NetduinoPlus;
using Toolbox.NETMF;


 

namespace EmailStockChecker
{
    public class clFinance
    {
        //MODIFED CODE FROM: http://www.jarloo.com/google-stock-api/ 

        //USER DEFINED
        private string Ticker;
        private double OwnedShares;

        //Gets from Online - GOOGLE
        //private string Company;
        //private string Exchange;
        private double Last;
        private double High;
        private double Low;
        private double Change;
        private double PercentChange;
        private double DailyChange;
        private double MarketValue;

        public clFinance(string ticker, double ownedShares)
        {
            //Constructor
            Ticker = ticker;
            OwnedShares = ownedShares;

            //Updates the info for the first time.
            UpdateStock();
        }
        public string GetTicker()
        {
            return Ticker;
        }
        public void UpdateStock(){
            FetchQuote(Ticker);
        }
        public double GetLastPrice()
        {
            return Last;
        }
        public double GetDailyChange()
        {
            return DailyChange;
        }
        public double GetMarketValue()
        {
            return MarketValue;
        }
        public double GetPercentChange()
        {
            return PercentChange;
        }
        public double GetChange()
        {
            return Change;
        }
        private void FetchQuote(string symbol)
        {
            string url = "http://www.google.com/ig/api?stock=" + symbol;

            string RawWebData = clMisc.GetOnlineWebPage(url,400,300);
            string tempString = "";

            //Parse the data
            //temp = clMisc.GetStringInBetween("<symbol data=\"", "\"/>", temp);
        
            //Company = clMisc.GetStringInBetween("<company data=\"","\"/>",RawWebData);
            //Exchange = clMisc.GetStringInBetween("<exchange data=\"","\"/>",RawWebData);
            try
            {
                string temp = clMisc.GetStringInBetween("<last data=\"", "\"/>", RawWebData);
                Last = Convert.ToDouble(clMisc.GetStringInBetween("<last data=\"", "\"/>", RawWebData));
                High = Convert.ToDouble(clMisc.GetStringInBetween("<high data=\"", "\"/>", RawWebData));
                Low = Double.Parse(clMisc.GetStringInBetween("<low data=\"", "\"/>", RawWebData));

                tempString = clMisc.GetStringInBetween("<change data=\"", "\"/>", RawWebData);
                //Fixes for negatives. For some reasons converting with the negative sign is not working. Do not know what is causing this.
                if (tempString.Substring(0, 1) == "-" && Double.Parse(tempString) >= 0)
                    Change = Double.Parse(tempString) * -1;
                else
                    Change = Double.Parse(tempString);

                tempString = clMisc.GetStringInBetween("<perc_change data=\"", "\"/>", RawWebData);
                //Fixes for negatives. For some reasons converting with the negative sign is not working. Do not know what is causing this.
                if (tempString.Substring(0, 1) == "-" && Double.Parse(tempString) >= 0)
                    PercentChange = Double.Parse(tempString) * -1; //PercentChange = ((int)((Double.Parse(tempString) * -1) * 100) / 100.0);
                else
                    PercentChange = Double.Parse(tempString); //PercentChange = ((int)((Double.Parse(tempString)) * 100) / 100.0);

                DailyChange = Change * OwnedShares; //* 100) / 100.0);
                MarketValue = Last * OwnedShares; ; //* 100) / 100.0);
            }
            catch
            {
                Last = 1;
                High = 2;
                Low = 3;
                Change = 4;
                PercentChange = 5;
            }
        }
        
    }
        
        
}


Steve


My Other Hobby: Engineer Turned Baker

#7 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 12 April 2012 - 11:27 PM

Nice work!

#8 smarcus3

smarcus3

    Advanced Member

  • Members
  • PipPipPip
  • 134 posts

Posted 12 April 2012 - 11:28 PM

Nice work!


Thanks
Steve


My Other Hobby: Engineer Turned Baker

#9 smarcus3

smarcus3

    Advanced Member

  • Members
  • PipPipPip
  • 134 posts

Posted 14 April 2012 - 09:47 PM

I finally got around to replacing my cardboard flag with an lexan one with imbedded LEDs. Here are a few pics of the 'finished' product. I'm sure I will keep tinkering with it.

All the LEDs ground sides are tacked together so only 5 wires have to run to the flag. I use a DO pin for each so they can be individually toggled.

Posted Image

Posted Image

Posted Image
Steve


My Other Hobby: Engineer Turned Baker

#10 smarcus3

smarcus3

    Advanced Member

  • Members
  • PipPipPip
  • 134 posts

Posted 15 April 2012 - 03:42 AM

A picture showing the LEDs on. There are 2 white and 2 red in the flag. A green LED shows power and a yellow blinks to notify the user the controller is working.

Posted Image

I have also just upgraded my N+ to 4.2 RC4 and loving it. It has more memory and syncs better. I haven't gotten one garbled lcd message with 4.2, fingers crossed.

I have also re-written some of my code to be smaller and more efficient. Below are all of the functions for my program.

Please comment or ask questions. Hope you enjoy it.

Progarm.cs
using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using System.IO;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.NetduinoPlus;
using FusionWare.SPOT.Hardware;
using MicroLiquidCrystal;
using System.Diagnostics;
using Servo_API;

 


namespace EmailStockChecker
{
    public class Program
    {
        public static void Main()
        {

            //LCD SECCTION

            Thread.Sleep(1000);

            // initialize i2c bus (only one instance is allowed)
            var bus = new I2CBus();

            // initialize provider (multiple devices can be attached to same bus)
            var lcdProvider = new MCP23008LcdTransferProvider(bus);

            // create the LCD interface
            var lcd = new Lcd(lcdProvider);
            
            // set up the LCD's number of columns and rows: 
            lcd.Begin(20, 4);

            lcd.BlinkCursor = true;

            // Print a message to the LCD.
            lcd.Clear();
            lcd.Write("STARTING UP ... ");
            lcd.SetCursorPosition(0, 2);
            lcd.Write("PLEASE WAIT ... ");

            //Stopwatch sw = Stopwatch.StartNew();

            //END OF LCD SECTION
            
            
            //Variable Decleration
            //DECLARE ALL STOCKS

            //int numberOfStocks = 6;
            int currentStockOnLCD = 1;


            //Thread.Sleep(1000);
            clFinance stockEEM = new clFinance("EEM", 100);
            clFinance stockEFA = new clFinance("EFA", 100);
            clFinance stockIJJ = new clFinance("IJJ", 100);
            clFinance stockIVV = new clFinance("IVV", 100);
            clFinance stockIJK = new clFinance("IJK", 100);
            clFinance stockVT = new clFinance("VT", 100);
            int unreadEmailCount = 0;



            Stopwatch StopWatchEmailChecker = Stopwatch.StartNew();
            //Stopwatch StopWatchStockChecker = Stopwatch.StartNew();
            Stopwatch StopWatchLCDChange = Stopwatch.StartNew();

            Boolean BlinkLEDs = false;
            int BlinkerCounter = 0;
            //Declare Servo
            Servo servo = new Servo(Pins.GPIO_PIN_D9);
            
            //Brings the servo home.
            servo.Degree = 0;

            bool isServoDown = true;

            //VARIABLE DECLERATION
            //const int SDA = 10; //Analog Pin 4
            //const int SCL = 11; //Analog Pin 5
            
            //LED SECTION

            //Already Hooked with On Board
            OutputPort onBoardLED = new OutputPort(Pins.ONBOARD_LED, false);
            OutputPort LED1 = new OutputPort(Pins.GPIO_PIN_D2, false);
            OutputPort LED2 = new OutputPort(Pins.GPIO_PIN_D3, false);
            OutputPort LED3 = new OutputPort(Pins.GPIO_PIN_D4, false);
            OutputPort LED4 = new OutputPort(Pins.GPIO_PIN_D5, false);
            OutputPort ActivityLED = new OutputPort(Pins.GPIO_PIN_D6, false);

            //END OF LED SECTION

            StopWatchLCDChange.Reset();
            StopWatchLCDChange.Start();

            StopWatchEmailChecker.Reset();
            StopWatchEmailChecker.Start();
            //Continuous Loop for the microcontroller
            while (true)
            {
                
                //Email Checker
                if (StopWatchEmailChecker.ElapsedMilliseconds > clConstants.EMAILUPDATETIME * 1000)
                {
                    unreadEmailCount = clEmail.GetUnreadEmailCount("www.smarcus3.x10.mx");

                    if (unreadEmailCount > 0)
                    {
                        //You have a message

                        //Raise Flag
                        if (isServoDown == true)
                        {
                            isServoDown = false;
                            for (int i = 0; i <= 180; i++)
                            {
                                servo.Degree = i;
                                Thread.Sleep(50);
                                
                            }

                            Thread.Sleep(1000);
                        }
                        servo.disengage();
                        //Blink LEDS
                        BlinkLEDs = true;
                    }
                    else
                    {
                        //No messages
                        LED1.Write(false);
                        LED2.Write(false);
                        LED3.Write(false);
                        LED4.Write(false);
                        //Lower Flag
                        

                        if (isServoDown == false)
                        {
                            isServoDown = true;
                            for (int i = 180; i >= 0; i--)
                            {
                                servo.Degree = i;
                                Thread.Sleep(50);
                                
                            }
                            Thread.Sleep(1000);
                        }
                        servo.disengage();
                        //Stop LEDS
                        BlinkLEDs = false;
                    }
                    StopWatchEmailChecker.Stop();
                    StopWatchEmailChecker.Reset();
                    StopWatchEmailChecker.Start();
                }

                //LCD SECTION

                if (StopWatchLCDChange.ElapsedMilliseconds >= 1000 * clConstants.STOCKUPDATETIME) //every 60 seconds
                {
                    if (BlinkLEDs == false)
                    {
                        LED1.Write(false);
                        LED2.Write(false);
                        LED3.Write(false);
                        LED4.Write(false);
                    }
                    else
                    {
                        LED1.Write(true);
                        LED2.Write(true);
                        LED3.Write(true);
                        LED4.Write(true);
                    }
                    switch (currentStockOnLCD)
                    {
                        case 1:
                            currentStockOnLCD += 1;
                            stockEEM.UpdateStock();
                            clMisc.updateLCDDisplay(stockEEM, lcd);
                            break;
                        case 2:
                            currentStockOnLCD += 1;
                            stockEFA.UpdateStock();
                            clMisc.updateLCDDisplay(stockEFA, lcd);
                            break;
                        case 3:
                            currentStockOnLCD += 1;
                            stockIJJ.UpdateStock();
                            clMisc.updateLCDDisplay(stockIJJ, lcd);
                            break;
                        case 4:
                            currentStockOnLCD += 1;
                            stockIJK.UpdateStock();
                            clMisc.updateLCDDisplay(stockIJK, lcd);
                            break;
                        case 5:
                            currentStockOnLCD += 1;
                            stockIVV.UpdateStock();
                            clMisc.updateLCDDisplay(stockIVV, lcd);
                            break;
                        case 6:
                            currentStockOnLCD = 1;
                            stockVT.UpdateStock();
                            clMisc.updateLCDDisplay(stockVT, lcd);
                            break;
                    }

                    StopWatchLCDChange.Stop();
                    StopWatchLCDChange.Reset();
                    StopWatchLCDChange.Start();
                    
                }

                //END OF LCD SECTION

                //LED SECTION

                if (BlinkLEDs)
                {
                    //Blinks half of the LEDs at a time. 
                    if (BlinkerCounter == 0)
                    {
                        clMisc.ToggleDigitalPins(LED1);
                        clMisc.ToggleDigitalPins(LED2);
                        BlinkerCounter = 1;
                    }
                    else
                    {
                        clMisc.ToggleDigitalPins(LED3);
                        clMisc.ToggleDigitalPins(LED4);
                        BlinkerCounter = 0;
                    }
                }
                else
                {
                    LED1.Write(false);
                    LED2.Write(false);
                    LED3.Write(false);
                    LED4.Write(false);
                }

                    //LED SECTION

                lcd.SetCursorPosition(19, 3);
                lcd.Write(((int)(clConstants.STOCKUPDATETIME - StopWatchLCDChange.ElapsedMilliseconds/1000)).ToString());

                //Blinks the onboard LED and ActivityLED
                clMisc.ToggleDigitalPins(onBoardLED);
                clMisc.ToggleDigitalPins(ActivityLED);
                //adds a pause in the controllers thread
                Thread.Sleep(100);

                //Debug.Print("Memory Left (Bytes): " + Debug.GC(false).ToString());
            }
        }

    }
    
}

clMisc.cs
using System;
//using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;

using System.IO;
using System.Text;
using MicroLiquidCrystal;
using System.Threading;
using Toolbox.NETMF.NET;



namespace EmailStockChecker
{
    public static class clMisc
    {
        
               
        public static string setDecimalPlaceOfString(double number, int decimalPlaces, bool placeCommas)
        {
            /* THIS FUNCTION TAKES IN A DOUBLE AND RETURNS IT IN A STRING WITH A SPECIFIED NUMBER OF DECIMAL 
             * PLACES WITH OR WITHOUT COMMAS. 
             * 
             * INPUT:   NUMBER          ---> DOUBLE WHICH CONTAINS THE UNFORMATTED NUMBER
             *          DECIMALPLACES   ---> INTEGER WHICH CONTAINS THE NUMBER OF WANTED DECIMALPLACES
             *          PLACECOMMAS     ---> BOOL WHEN TRUE COMMAS ARE INSERTED INTO THE OUTPUTTED STRING
             * 
             * OUTPUT: A STRING WHICH HAS THE APPROPRIATE NUMBER OF DECIMAL PLACES WITH COMMAS IF REQUESTED.
             */
            //string tempstr = "";
            StringBuilder builder = new StringBuilder();
            //This path is for doubles which already have a decimal place. adds commas as needed to the string
            if (number.ToString().IndexOf('.') >= 0)
            {
                if (number.ToString().Length - number.ToString().IndexOf('.') - 1 >= decimalPlaces)
                    builder.Append(number.ToString().Substring(0, number.ToString().IndexOf('.') + decimalPlaces + 1));
                else
                {
                    builder.Append(number.ToString());
                    for (int i = number.ToString().Length - 1; i < number.ToString().IndexOf('.') + decimalPlaces; i++)
                    {

                        builder.Append("0");

                    }
                }

                if (placeCommas == true)
                {
                    string tempstr;
                    for (int i = builder.Length - 6; i > 0; i = i - 3)
                    {
                        //tempstr = tempstr.Substring(0, i) + "," + tempstr.Substring(i, tempstr.Length - i);
                        tempstr = builder.ToString();
                        builder.Clear();
                        builder.Append(tempstr.Substring(0, i));
                        builder.Append(",");
                        builder.Append(tempstr.Substring(i, tempstr.Length - i));

                    }
                }
                return builder.ToString(); //return number.ToString().Substring(0, number.ToString().IndexOf('.') + decimalPlaces + 1);
            }
            //If there isn't a deciaml in the number
            else
            {
                builder.Append(number.ToString());
                for (int i = 0; i < decimalPlaces; i++)
                {
                    if (i == 0)
                        builder.Append(".");
                    builder.Append("0");

                }

                if (placeCommas == true)
                {
                    string tempstr;
                    for (int i = builder.Length - 6; i > 0; i = i - 3)
                    {
                        //tempstr = tempstr.Substring(0, i) + "," + tempstr.Substring(i, tempstr.Length - i);
                        tempstr = builder.ToString();
                        builder.Clear();
                        builder.Append(tempstr.Substring(0, i));
                        builder.Append(",");
                        builder.Append(tempstr.Substring(i, tempstr.Length - i));

                    }
                }
                return builder.ToString();
            }
        }
        
        public static string centerString(string sourceString1, string sourceString2)
        {
            /*THIS FUNCTION TAKES IN TWO STRINGS AND CENTERS IT IN THE OUTPUTTED STRING. THIS RETURNED STRING'S 
             * LENGTH IS DETERMINED BY THE INTEGER, FORMATTEDSTRINGLENGTH.
             * 
             * INPUTS:  SOURCESTRING1           ---> STRING CONTAINING A STRING NEEDED TO BE CENTERED
             *          SOURCESTRING2           ---> STRING CONTAINING A STRING NEEDED TO BE CENTERED
             *          FORMATTEDSTRINGLENGTH   ---> INTEGER SPECIFING THE LENGTH OF THE RETURNED STRING
             * 
             * OUTPUT:  A STRING THE LENGTH OF FORMATTEDSTRINGLEGTH THAT CENTERS THE SOURCESTRINGS
             */ 
            //string formattedString = "";
            StringBuilder sb = new StringBuilder();
            if (sourceString1.Length + sourceString2.Length < clConstants.LCDWIDTH)
            {
                int diference = (int) (clConstants.LCDWIDTH - sourceString1.Length -  sourceString2.Length)/3;

                //only 2 spaces
                if (diference == 0 && clConstants.LCDWIDTH - sourceString1.Length - sourceString2.Length >= 2)
                {
                    diference = 1;
                }

                //only 1 space
                if (diference == 0 && clConstants.LCDWIDTH - sourceString1.Length - sourceString2.Length == 1)
                    return sourceString1 + " " + sourceString2;

                for (int i = 0; i < clConstants.LCDWIDTH; i++)
                {
                    if (i < diference)
                    {
                        //formattedString = formattedString + " ";
                        sb.Append(" ");
                    }
                    else if (i < sourceString1.Length + diference)
                    {
                        //formattedString = formattedString + sourceString1;
                        sb.Append(sourceString1);
                        i = diference + sourceString1.Length - 1;
                    }
                    else if (i < sourceString1.Length + 2 * diference)
                    {
                        //formattedString = formattedString + " ";
                        sb.Append(" ");
                    }
                    else if (i < sourceString1.Length + sourceString2.Length + 2 * diference)
                    {
                        //formattedString = formattedString + sourceString2;
                        sb.Append(sourceString2);
                        i = sourceString1.Length + sourceString2.Length + 2 * diference - 1;
                    }
                    else
                    {
                        //formattedString = formattedString + " ";
                        sb.Append(" ");
                    }
                }

                return sb.ToString();//formattedString;
            }
            else
                return sourceString1 + sourceString2;
        }
        public static string centerString(string sourceString)
        {
            /*THIS FUNCTION TAKES IN ONE STRINGS AND CENTERS IT IN THE OUTPUTTED STRING. THIS RETURNED STRING'S 
             * LENGTH IS DETERMINED BY THE INTEGER, FORMATTEDSTRINGLENGTH.
             * 
             * INPUTS:  SOURCESTRING1           ---> STRING CONTAINING A STRING NEEDED TO BE CENTERED
             *          FORMATTEDSTRINGLENGTH   ---> INTEGER SPECIFING THE LENGTH OF THE RETURNED STRING
             * 
             * OUTPUT:  A STRING THE LENGTH OF FORMATTEDSTRINGLEGTH THAT CENTERS THE SOURCESTRING
             */ 
            //string formattedString = "";
            StringBuilder sb = new StringBuilder();

            if (sourceString.Length < clConstants.LCDWIDTH)
            {
                int diference = clConstants.LCDWIDTH - sourceString.Length;
                for (int i = 0; i < clConstants.LCDWIDTH; i++)
                {
                    if (i < (int)diference / 2)
                    {
                        sb.Append(" ");
                        //formattedString = formattedString + " ";
                    }
                    else if (i < sourceString.Length + (int)diference / 2)
                    {
                        sb.Append(sourceString);
                        //formattedString = formattedString + sourceString;
                        i = (int)diference / 2 + sourceString.Length - 1;
                    }
                    else
                    {
                        //formattedString = formattedString + " ";
                        sb.Append(" ");
                    }
                }

                return sb.ToString(); // formattedString = formattedString.Substring(0, clConstants.LCDWIDTH);
            }
            else
                //forces it to be the right length
                return sourceString.Substring(0, clConstants.LCDWIDTH);
        }
        public static void updateLCDDisplay(clFinance Stock, Lcd lcd) //needs LCD in it
        {
            /* THIS IS A HELPER FUNCTION WHICH IS CALLED TO UPDATE THE DISPLAY OF THE LCD DISPLAY WITH THE 
             * INPUTTED STOCK. THIS FUNCTION KEEPS THE MAIN FUNCTION CLEAN.
             * 
             *                  //     LCD Display     //
             *
             *                  //        LAYOUT       // 
             *                  //  STOCK NAME   LAST  //
             *                  //    CHANGE PERCENT   //
             *                  //   DAILY  -  CHANGE  //
             *                  //    MARKET VALUE     //
             * 
             */ 
            
            //20 x 4 size LCD

            

            string formattedStockName = "";
            string formattedMarketValue = "";
            string formattedDailyChange = "";
            string formattedChange = "";
            string formattedPercChange = "";
            string formattedLast = "";


            //Stock Name
            //if (Stock.GetStockName().Length > 20)
                formattedStockName = Stock.GetTicker();
            //else
            //    formattedStockName = Stock.GetStockName();

            //Change
            if (Stock.GetChange() > 0)
                formattedChange = "$" + setDecimalPlaceOfString(Stock.GetChange(), 2, true);
            else
                formattedChange = "-$" + setDecimalPlaceOfString(Stock.GetChange() * -1,2, true);
            
            //Percent
            formattedPercChange = setDecimalPlaceOfString(Stock.GetPercentChange(), 2, true) +"%";

            //Daily Change
            if (Stock.GetDailyChange() > 0)
                formattedDailyChange = "$" + setDecimalPlaceOfString(Stock.GetDailyChange(),2, true);
            else
                formattedDailyChange = "-$" + setDecimalPlaceOfString(Stock.GetDailyChange() * -1, 2, true);
            
            //Market Value
            if (Stock.GetMarketValue() > 0)
                formattedMarketValue = "$" + setDecimalPlaceOfString(Stock.GetMarketValue(), 2,true);
            else
                formattedMarketValue = "-$" + setDecimalPlaceOfString(Stock.GetMarketValue() * -1, 2,true);

            //Last
            formattedLast = "$" + setDecimalPlaceOfString(Stock.GetLastPrice(), 2, true);

            lcd.Clear();
            //lcd.SetCursorPosition(0, 0);
            Thread.Sleep(clConstants.DELAYBETWEENLCDWRITEMS);

            //Row 1
            clMisc.wrtieCharbyCharLCD(lcd, centerString(formattedStockName, formattedLast), 0);

            //Row 2
            clMisc.wrtieCharbyCharLCD(lcd, centerString(formattedChange, formattedPercChange), 1);

            //Row 3
            clMisc.wrtieCharbyCharLCD(lcd, centerString(formattedDailyChange), 2);

            //Row 4

            clMisc.wrtieCharbyCharLCD(lcd, centerString(formattedMarketValue), 3);
            //TESTING CODE

            lcd.SetCursorPosition(clConstants.LCDWIDTH - 1, clConstants.LCDHEIGHT - 1);

            //string temp2 = center2String(formattedStockName,formattedLast, 20);
            //string temp3 = center2String(formattedChange, formattedPercChange, 20);
            //string temp1 = center1String(formattedDailyChange, 20);
            //string temp = center1String(formattedMarketValue, 20);

        }
        public static void wrtieCharbyCharLCD(Lcd lcd, string inputString, int cursorStartRow)
        {
            
            lcd.SetCursorPosition(0, cursorStartRow); //COLUMN ROW
            for (int i = 0; i < inputString.Length; i++)
            {
                if (inputString[i].ToString() != " ")
                {
                    Thread.Sleep(clConstants.DELAYBETWEENLCDWRITEMS);
                    lcd.SetCursorPosition(i, cursorStartRow);
                    lcd.Write(inputString[i].ToString());
                }
            }
        }
        public static void ToggleDigitalPins(OutputPort outPort)
        {
            /* THIS FUNCTION TAKES IN A PORT AND SWAPS THE STATE OF THE DIGITAL PIN. THIS MEANS THAT IF A PIN
             * IS HIGH (5V) IT IS SWITCHED TO LOW (0V). THE OPPOSITE IS ALSO TRUE. 
             * 
             * INPUT:   OUTPORT --->    TAKES IN AN OUTPORT PIN WHICH IS GOING TO BE TOGGED TO THE STATE IT IS NOT 
             *                          CURRENTLY IN.
             */
            if (outPort.Read())
                outPort.Write(false);
            else
                outPort.Write(true);
        }
        public static string GetStringInBetween(string strBegin, string strEnd, string strSource)
        {
            /* THIS FUNCTION RETURNS A STRING WHICH IS BETWEEN TWO SPECIFIED STRINGS. THESE TWO SEARCH STRINGS ENCAPSULATE
             * THE TARGET STRING WHICH IS GOING TO BE FOUND. THIS FUNCTION IS VERY USEFUL TO PULL INFORMATION
             * FROM A LONG STRING SUCH AS THE OUTPUT FROM AN ONLINE WEBSITE. THIS USE IS THE REASON WHY THIS FUNCTION WAS
             * WRITTEN FOR THIS EXPLICIT REASON.
             * 
             * INPUTS:  STRBEGIN    --->    THE FIRST STRING THAT MARKS THE BEGINNING OF THE STRING WHICH IS GOING TO BE FOUND
             *          STREND      --->    THE SECOND STRING THAT MARKS THE END OF THE STRING WHICH IS GOING TO BE FOUND
             *          STRSOURCE   --->    THE SOURCE STRING THAT HAS THE STRBEGIN AND STREND IN IT. THIS STRING ALSO HOLDS THE
             *                              TARGET STRING WHICH IS GOING TO BE FOUND.
             *                              
             * OUTPUT:  A STRING WHICH WAS BETWEEN STRBEGIN AND STREND AND CONTAINED IN STRSOURCE
             */
            string result = "";
            int iIndexOfBegin = strSource.IndexOf(strBegin);
            if (iIndexOfBegin != -1)
            {
                strSource = strSource.Substring(iIndexOfBegin+strBegin.Length);
                int iEnd = strSource.IndexOf(strEnd);
                if (iEnd != -1)
                {
                    result = strSource.Substring(0, iEnd);
                }
            }
            else
                // stay where we are
                result = strSource;

            return result;
        }
        public static string GetOnlineWebPage(string url, string pageLocation)
        {
            /* THIS FUNCTION GETS ONLINEWEBPAGES AS LONG AS THEY ARE NOT HTTPS. THE NETDUINO AT THIS POINT DOESNT
             * HANDLE DEALING WITH HTTPS PAGES OR SSL. THE WORK AROUND TO THIS IS TO USE AN PHP WEBSITE. THE FUNCITON 
             * RETURNS THE ENTIRE WEBSITE AS A LONG, LONG STRING. ALL OF THE HTML WILL BE RETURNED WITH THIS FUNCTION
             * SUCH AS HEADER AND BODY BREAKS. THIS FUNCTION GOES HAND IN HAND WITH GETSTRINGINBETWEEN
             * 
             * INPUT:   URL     --->    A STRING WHICH CONTAINS THE URL OF THE SITE SUCH AS HTTP://WWW.GMAIL.COM
             * 
             * OUTPUT:  A STRING WHICH CONTAINS ALL THE RAW DATA OF THE WEBSITE
             * 
             * SAMPLE CALL:         clMisc.getOnlineWebPage("www.smarcus3.x10.mx");
             * 
             * BASED ON THE INTEGRATEDSOCKET EXAMPLE
             */
            //string Text = "";
            StringBuilder sb = new StringBuilder();

            // Defines the socket, including the remote host and port
            SimpleSocket Socket = new IntegratedSocket(url, 80); //SimpleSocket Socket = new IntegratedSocket("www.smarcus3.x10.mx", 80);

            // Connects to the socket
            Socket.Connect();

            // /ig/api?stock=EEM for finance
            // / for the root file i.e. emails

            // Does a plain HTTP request
            Socket.Send("GET " + pageLocation + " HTTP/1.1\r\n");
            Socket.Send("Host: " + Socket.Hostname + "\r\n");
            Socket.Send("Connection: Close\r\n");
            Socket.Send("\r\n");


            // Prints all received data to the debug window, until the connection is terminated and there's no data left anymore
            while (Socket.IsConnected || Socket.BytesAvailable > 0)
            {
                sb.Append(Socket.Receive());
            }
            
            // Closes down the socket
            Socket.Close();

            return sb.ToString();
        }
        

        public static char[] Bytes2Chars(byte[] Input)
        {
            char[] Output = new char[Input.Length];
            for (int Counter = 0; Counter < Input.Length; ++Counter)
                Output[Counter] = (char)Input[Counter];
            return Output;
        }

        /// <summary>
        /// Converts a char array to a byte array
        /// </summary>
        /// <param name="Input">The char array</param>
        /// <returns>The byte array</returns>
        public static byte[] Chars2Bytes(char[] Input)
        {
            byte[] Output = new byte[Input.Length];
            for (int Counter = 0; Counter < Input.Length; ++Counter)
                Output[Counter] = (byte)Input[Counter];
            return Output;
        }
    }
    
}

clEmail.cs
using System;

using Microsoft.SPOT;

namespace EmailStockChecker
{
    public static class clEmail
    {
        public static int GetUnreadEmailCount(string url)
        {
            string rawData = clMisc.GetOnlineWebPage(url,"/");
            try
            {
                return Int32.Parse(clMisc.GetStringInBetween("UNREAD_", "_UNREAD", rawData));
            }
            catch
            {
                //For when the webpage cannot be grabbed
                return 0;
            }
        }
    }
}

clFinance.cs
using System;
using System.Threading;
using System.IO.Ports;
using System.Text;
using System.IO;
using Microsoft.SPOT;

using SecretLabs.NETMF.Hardware.NetduinoPlus;


 

namespace EmailStockChecker
{
    public class clFinance
    {
        //MODIFED CODE FROM: http://www.jarloo.com/google-stock-api/ 

        //USER DEFINED
        private string Ticker;
        private double OwnedShares;

        //Gets from Online - GOOGLE
        //private string Company;
        //private string Exchange;
        private double Last;
        private double Change;
        private double PercentChange;
        private double DailyChange;
        private double MarketValue;

        public clFinance(string ticker, double ownedShares)
        {
            //Constructor
            Ticker = ticker;
            OwnedShares = ownedShares;

            //Updates the info for the first time.
            //UpdateStock();
        }
        public string GetTicker()
        {
            return Ticker;
        }
        public void UpdateStock(){
            FetchQuote(Ticker);
        }
        public double GetLastPrice()
        {
            return Last;
        }
        public double GetDailyChange()
        {
            return DailyChange;
        }
        public double GetMarketValue()
        {
            return MarketValue;
        }
        public double GetPercentChange()
        {
            return PercentChange;
        }
        public double GetChange()
        {
            return Change;
        }
        private void FetchQuote(string symbol)
        {
            //string url = "www.google.com"; //ig/api?stock=" + symbol; //string url = "http://www.google.com/ig/api?stock=" + symbol;
            //string temp = clMisc.GetOnlineWebPage("www.google.com","/ig/api?stock=EEM");
            string RawWebData = clMisc.GetOnlineWebPage("www.google.com", "/ig/api?stock=" + symbol); //,400,300);
            string tempString = "";


            //Parse the data
            //temp = clMisc.GetStringInBetween("<symbol data=\"", "\"/>", temp);
        
            //Company = clMisc.GetStringInBetween("<company data=\"","\"/>",RawWebData);
            //Exchange = clMisc.GetStringInBetween("<exchange data=\"","\"/>",RawWebData);
            
            //Try Catch incase data couldn't be read from the website.
            try
            {
                string temp = clMisc.GetStringInBetween("<last data=\"", "\"/>", RawWebData);
                Last = Double.Parse(clMisc.GetStringInBetween("<last data=\"", "\"/>", RawWebData));
                
                tempString = clMisc.GetStringInBetween("<change data=\"", "\"/>", RawWebData);
                //Fixes for negatives. For some reasons converting with the negative sign is not working. Do not know what is causing this.
                if (tempString.Substring(0, 1) == "-" && Double.Parse(tempString) >= 0)
                    Change = Double.Parse(tempString) * -1;
                else
                    Change = Double.Parse(tempString);

                tempString = clMisc.GetStringInBetween("<perc_change data=\"", "\"/>", RawWebData);
                //Fixes for negatives. For some reasons converting with the negative sign is not working. Do not know what is causing this.
                if (tempString.Substring(0, 1) == "-" && Double.Parse(tempString) >= 0)
                    PercentChange = Double.Parse(tempString) * -1; //PercentChange = ((int)((Double.Parse(tempString) * -1) * 100) / 100.0);
                else
                    PercentChange = Double.Parse(tempString); //PercentChange = ((int)((Double.Parse(tempString)) * 100) / 100.0);

                DailyChange = Change * OwnedShares; //* 100) / 100.0);
                MarketValue = Last * OwnedShares; ; //* 100) / 100.0);
            }
            catch
            {
                Last = 1;
                
                Change = 4;
                PercentChange = 5;
                DailyChange = 123;
                MarketValue = 4556;
            }
        }
        
    }
        
        
}


Servo.cs
/*
 * Servo NETMF Driver
 *      Coded by Chris Seto August 2010
 *      <chris@chrisseto.com> 
 *      
 * Use this code for whatveer you want. Modify it, redistribute it, I don't care.
 * I do ask that you please keep this header intact, however.
 * If you modfy the driver, please include your contribution below:
 * 
 * Chris Seto: Inital release (1.0)
 * Chris Seto: Netduino port (1.0 -> Netduino branch)
 * 
 * 
 * */

using System;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;

namespace Servo_API
{
    public class Servo : IDisposable
    {
        /// <summary>
        /// PWM handle
        /// </summary>
        private PWM servo;

        /// <summary>
        /// Timings range
        /// </summary>
        private int[] range = new int[2];

        /// <summary>
        /// Set servo inversion
        /// </summary>
        public bool inverted = false;

        /// <summary>
        /// Create the PWM pin, set it low and configure timings
        /// </summary>
        /// <param name="pin"></param>
        public Servo(Cpu.Pin pin)
        {
            // Init the PWM pin
            servo = new PWM((Cpu.Pin)pin);

            // See what the Netduino team say about this... 
            //servo.Set(false);

            // Typical settings
            range[0] = 1000;
            range[1] = 2000;
        }

        public void Dispose()
        {
            servo.Dispose();
        }

        /// <summary>
        /// Allow the user to set cutom timings
        /// </summary>
        /// <param name="fullLeft"></param>
        /// <param name="fullRight"></param>
        public void setRange(int fullLeft, int fullRight)
        {
            range[1] = fullLeft;
            range[0] = fullRight;
        }

        /// <summary>
        /// Disengage the servo. 
        /// The servo motor will stop trying to maintain an angle
        /// </summary>
        public void disengage()
        {
            // See what the Netduino team say about this... 
            servo.SetDutyCycle(0);
        }

        /// <summary>
        /// Set the servo degree
        /// </summary>
        public double Degree
        {
            set
            {
                /// Range checks
                if (value > 180)
                    value = 180;

                if (value < 0)
                    value = 0;

                // Are we inverted?
                if (inverted)
                    value = 180 - value;

                // Set the pulse
                servo.SetPulse(20000, (uint)map((long)value, 0, 180, range[0], range[1]));
            }
        }

        /// <summary>
        /// Used internally to map a value of one scale to another
        /// </summary>
        /// <param name="x"></param>
        /// <param name="in_min"></param>
        /// <param name="in_max"></param>
        /// <param name="out_min"></param>
        /// <param name="out_max"></param>
        /// <returns></returns>
        private long map(long x, long in_min, long in_max, long out_min, long out_max)
        {
            return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
        }
    }
}

Steve


My Other Hobby: Engineer Turned Baker

#11 smarcus3

smarcus3

    Advanced Member

  • Members
  • PipPipPip
  • 134 posts

Posted 15 April 2012 - 06:38 PM

Whats better than getting notified of emails and stock data ...

Getting the weather as well. I decided to parse yahoo's weather api data and add it along side the stock data on the LCD screen. Below are a few screenshots and the new clWeather.cs The code isn't optimized, but just a first pass. The number in the bottom right corner is the number of seconds till the screen updates.

Posted Image

Posted Image

using System;
using Microsoft.SPOT;
using MicroLiquidCrystal;

namespace EmailStockChecker
{
    public static class clWeather
    {                                                                                      
        public static void GetWeatherWriteToLCD(Lcd lcd, bool CurrentConditions)
        {
            /*                          LCD DISPLAY
             * 
             *                           WEATHER
             *              currentTemperature      currentDate
             *                      currentConditions
             *                    currentHIGHLOW
             * 
             * 
             */ 
            
            
            string rawTempData = clMisc.GetOnlineWebPage("weather.yahooapis.com", "/forecastrss?w=12770733&u=f");
            rawTempData = clMisc.GetStringInBetween("<![CDATA[", "]]>", rawTempData);
            
            string currentTemperature = clMisc.GetStringInBetween("Current Conditions:</b><br/>\n", "F<BR/>", rawTempData);
            currentTemperature = clMisc.GetStringInBetween(", ", " ", currentTemperature) + " F";

            //string currentConditions = clMisc.GetStringInBetween("Current Conditions:</b><br />\n", ", ", rawTempData);

            string rawHighLow = clMisc.GetStringInBetween("Forecast:</b><BR />\n", "<br />\n<br />\n<a ", rawTempData);
            string currentdate = rawHighLow.Substring(0, 3);
            string currentHighLow = clMisc.GetStringInBetween("", "<br />\n", rawHighLow);
            currentHighLow = currentHighLow.Substring(6);
            string tomorrowHighLow = rawHighLow.Substring(currentHighLow.Length+7+12-6);
            string tomorrowdate = tomorrowHighLow.Substring(0, 3);
            tomorrowHighLow = tomorrowHighLow.Substring(6);

            string currentConditions = clMisc.GetStringInBetween("", ". ", currentHighLow);
            currentHighLow = currentHighLow.Substring(currentConditions.Length+2);

            string tomorrowConditions = clMisc.GetStringInBetween("", ". ", tomorrowHighLow);
            tomorrowHighLow = tomorrowHighLow.Substring(tomorrowConditions.Length + 2);

            if (CurrentConditions == true)
            {
                lcd.Clear();

                clMisc.wrtieCharbyCharLCD(lcd, clMisc.centerString("CURRENT WEATHER"), 0);
                clMisc.wrtieCharbyCharLCD(lcd, clMisc.centerString(currentTemperature, currentdate), 1);
                clMisc.wrtieCharbyCharLCD(lcd, clMisc.centerString(currentConditions), 2);
                clMisc.wrtieCharbyCharLCD(lcd, clMisc.centerString(currentHighLow), 3);
            }
            else
            {
                lcd.Clear();
                
                clMisc.wrtieCharbyCharLCD(lcd, clMisc.centerString("FORECAST WEATHER"), 0);
                clMisc.wrtieCharbyCharLCD(lcd, clMisc.centerString(tomorrowdate), 1);
                clMisc.wrtieCharbyCharLCD(lcd, clMisc.centerString(tomorrowConditions), 2);
                clMisc.wrtieCharbyCharLCD(lcd, clMisc.centerString(tomorrowHighLow), 3);
            }

            return;
        }
    }
}

Steve


My Other Hobby: Engineer Turned Baker




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.