Skip to content
This repository has been archived by the owner on Jan 3, 2020. It is now read-only.

Fix the bug that analogRead and digitalRead doesn't work on Leonardo. #69

Merged
merged 2 commits into from
Oct 29, 2015
Merged

Fix the bug that analogRead and digitalRead doesn't work on Leonardo. #69

merged 2 commits into from
Oct 29, 2015

Conversation

jimaobian
Copy link
Contributor

The DTR should be enable. Other wise serial read cannot work on Leonardo.

The DTR should be enable. Other wise serial read cannot work.
@msftclas
Copy link

Hi @jimaobian, I'm your friendly neighborhood Microsoft Pull Request Bot (You can call me MSBOT). Thanks for your contribution!

This seems like a small (but important) contribution, so no Contribution License Agreement is required at this point. Real humans will now evaluate your PR.

TTYL, MSBOT;

@ooeygui
Copy link
Member

ooeygui commented Oct 26, 2015

Hi there @jimaobian. Have you tested this on an Arduino Uno?

@jimaobian
Copy link
Contributor Author

Actually the DTR signal will cause a hardware reset on the Uno.
There will be about 2~3 seconds delay for running the boot loader and setting up the Firmata.
This is also the reason why Uno may discard some data after a refresh boot up.
Just give Uno some time :)

On the contrary the DTR signal will only cause the hardware reset on the Leonardo, but not run the boot loader. So there is no data loss problem.

However if DTR signal is not set on Leonardo, data cannot send from Leonardo to Raspberry Pi, which cause my issue.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

using Microsoft.Maker.Firmata;
using Microsoft.Maker.RemoteWiring;
using Microsoft.Maker.Serial;

// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409

namespace blink
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        UsbSerial usb;
        RemoteDevice arduino;
        private DispatcherTimer loopTimer, setupTimer;
        private const int LED_PIN = 13;
        private PinState pinValue;

        public MainPage()
        {
            this.InitializeComponent();

           // usb = new UsbSerial("VID_2341", "PID_8036");   //I've written in my device D directly Leonardo

            usb = new UsbSerial("VID_2341", "PID_0043");   //I've written in my device D directly UNO
            arduino = new RemoteDevice(usb);

            usb.ConnectionEstablished += OnConnectionEstablished;

            //SerialConfig.8N1 is the default config for Arduino devices over USB
            usb.begin(57600, SerialConfig.SERIAL_8N1);
        }

        private void OnConnectionEstablished()
        {
            System.Diagnostics.Debug.WriteLine("Connection Established");
            setupTimer = new DispatcherTimer();
            setupTimer.Tick += setup;
            setupTimer.Interval = TimeSpan.FromMilliseconds(3000);
            setupTimer.Start();
        }

        private void setup(object sender, object e)
        {
            setupTimer.Stop();
            System.Diagnostics.Debug.WriteLine("Setup");

            arduino.pinMode("A0", PinMode.ANALOG);
            arduino.pinMode(LED_PIN, PinMode.OUTPUT);

            loopTimer = new DispatcherTimer();
            loopTimer.Interval = TimeSpan.FromMilliseconds(1000);
            loopTimer.Tick += loop;
            loopTimer.Start();
        }

        private void loop(object sender, object e)
        {
            int theValue = arduino.analogRead("A0");
            System.Diagnostics.Debug.WriteLine(theValue);
            if (pinValue == PinState.HIGH)
            {
                arduino.digitalWrite(LED_PIN, PinState.LOW);
                System.Diagnostics.Debug.WriteLine("OFF");
                pinValue = PinState.LOW;
            }
            else
            {
                arduino.digitalWrite(LED_PIN, PinState.HIGH);
                System.Diagnostics.Debug.WriteLine("ON");
                pinValue = PinState.HIGH;
            }
        }
    }
}

@turkycat
Copy link
Contributor

I have not had a chance to test your changes yet, but it is better to add an event to RemoteDevice's DeviceReady event rather than the IStream object's ConnectionEstablished. The reason is that there is some handshaking that occurs between RemoteDevice and the Arduino. It will repeat the process up to 30 times until the handshaking is successful, or it will report an error if failed (through DeviceConnectionFailed event).

@jimaobian
Copy link
Contributor Author

Great! It works

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

using Microsoft.Maker.Firmata;
using Microsoft.Maker.RemoteWiring;
using Microsoft.Maker.Serial;

// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409

namespace blink
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        UsbSerial usb;
        RemoteDevice arduino;
        private DispatcherTimer loopTimer;//, setupTimer;
        private const int LED_PIN = 13;
        private PinState pinValue;

        public MainPage()
        {
            this.InitializeComponent();

           // usb = new UsbSerial("VID_2341", "PID_8036");   //I've written in my device D directly Leonardo

            usb = new UsbSerial("VID_2341", "PID_0043");   //I've written in my device D directly UNO
            arduino = new RemoteDevice(usb);
            arduino.DeviceReady += onDeviceReady;

            //SerialConfig.8N1 is the default config for Arduino devices over USB
            usb.begin(57600, SerialConfig.SERIAL_8N1);
        }

        private void onDeviceReady()
        {
            System.Diagnostics.Debug.WriteLine("Device Ready");

            var action = Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, new Windows.UI.Core.DispatchedHandler(() =>
            {
                setup();
            }));
        }

        private void setup()
        {
            System.Diagnostics.Debug.WriteLine("Setup");

            arduino.pinMode("A0", PinMode.ANALOG);
            arduino.pinMode(LED_PIN, PinMode.OUTPUT);

            loopTimer = new DispatcherTimer();
            loopTimer.Interval = TimeSpan.FromMilliseconds(1000);
            loopTimer.Tick += loop;
            loopTimer.Start();
        }

        private void loop(object sender, object e)
        {
            int theValue = arduino.analogRead("A0");
            System.Diagnostics.Debug.WriteLine(theValue);
            if (pinValue == PinState.HIGH)
            {
                arduino.digitalWrite(LED_PIN, PinState.LOW);
                System.Diagnostics.Debug.WriteLine("OFF");
                pinValue = PinState.LOW;
            }
            else
            {
                arduino.digitalWrite(LED_PIN, PinState.HIGH);
                System.Diagnostics.Debug.WriteLine("ON");
                pinValue = PinState.HIGH;
            }
        }
    }
}

@jimaobian
Copy link
Contributor Author

The code works both on Uno and Leonardo.
After testing, please pass the PR as soon as possible :)
Thanks~

@turkycat
Copy link
Contributor

Tested well on Uno (restart confirmed), Leo, and DFRobot Bluno. After a discussion with the team, we are not concerned with the rebooting on Uno. Nice work @jimaobian!

@@ -329,6 +329,7 @@ UsbSerial::connectToDeviceAsync(
// Configure the device properties
_serial_device->Handshake = SerialHandshake::None;
_serial_device->BaudRate = _baud;
_serial_device->IsDataTerminalReadyEnabled = true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please change these 2 tabs to 8 spaces and I will accept your PR!

@jimaobian
Copy link
Contributor Author

Done

ooeygui added a commit that referenced this pull request Oct 29, 2015
Fix the bug that analogRead and digitalRead doesn't work on Leonardo.
@ooeygui ooeygui merged commit 6f8c4a4 into ms-iot:develop Oct 29, 2015
@zfields
Copy link
Contributor

zfields commented Oct 29, 2015

Excellent catch! I'm happy to see this get fixed! Thanks!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants