Coder Social home page Coder Social logo

ms-iot / remote-wiring Goto Github PK

View Code? Open in Web Editor NEW
195.0 42.0 125.0 1.56 MB

A remote "Arduino Wiring" interface to control an Arduino compatible device from a Windows 10 Universal Windows Application. NOTE: The projects for Windows 8.1 and Windows Phone 8.1 are no longer maintained, but have been left in place to facilitate makers using those platforms.

Home Page: https://microsoft.hackster.io/windowsiot/basic-windows-remote-arduino

License: MIT License

C++ 73.00% C 0.19% C# 26.81%

remote-wiring's Introduction

Windows Remote Arduino

Windows Remote Arduino is an open-source Windows Runtime Component library which allows Makers to control an Arduino through a Bluetooth, USB, WiFi, or Ethernet connection! It is intended for Windows Runtime (WinRT) Developers who want to harness the power of Arduino hardware using the Windows Runtime Languages. Developers who include this component in their projects will automatically have access to its features in any of the WinRT languages (C++/CX, C# and JavaScript). The library is built on top of the Firmata protocol, which is implemented in a pre-packaged Firmata library included in the Arduino software obtained from http://arduino.cc.

View the open-source license.

tl;dr
Preview Remote Arduino with Windows Remote Arduino Experience!
Get started with your own project

Overview

Windows Remote Arduino bridges the gap between the software world and the physical world. By leveraging the power of Windows 10 we are able to expose new possibilities of Windows devices such as a Windows Phone, Surface Pro 3, Windows desktop, and even Raspberry Pi 2. Pair your device with an Arduino and gain access to a whole new set of realities with the world at your fingertips.

Preview Windows Remote Arduino

We have released a Universal Windows Application (UWA) called Windows Remote Arduino Experience which will allow you to explore GPIO, Analog, and PWM functionality from any device running Windows 10, including Windows IoT Core devices like Raspberry Pi 2! The app is open source and will allow you to connect to and control your Arduino without writing a single line of code!

  1. Upload StandardFirmata to your Arduino - take note of the baud rate that StandardFirmata has set.
  2. Download Windows Remote Arduino Experience from the Windows Store or download the source code and deploy it from Visual Studio!
  3. Make sure to choose the proper baud rate when connecting to your device. Bluetooth devices may require a specific baud rate, and both StandardFirmata and Windows Remote Arduino need to agree on this setting!

5 Steps to Your Remote Arduino Project

This section covers the basics of creating your own project to use Windows Remote Arduino. You can always clone the samples repository for a quick dive into some existing examples!

  1. Upload StandardFirmata to your Arduino
  2. Create a project or use a sample project
  3. Choose your connection method. Serial Commuinication like USB and Bluetooth have a couple settings to verify, while there is also an entire guide on hooking up your Bluetooth device. You can also use Ethernet or WiFi, but must have the appropriate hardware.
  4. Verify your package.appxmanifest file in your Windows solution contains the necessary device capabilities.
  5. Review the usage to get started writing your Remote Arduino code!

Functionality

Windows Remote Arduino enables the following functionality, right "out of the box".

  1. GPIO – Analog and Digital I/O
  • digitalWrite - Digital Write
  • digitalRead - Digital Read
  • analogWrite - Analog Write
  • analogRead - Analog Read
  • pinMode - Set the mode for any pins.
  • Eventing - receive events when values change / are reported.
  1. I2C/TwoWire
  • Send/Receive data to and from other devices over I2C.
  1. Custom protocols via Firmata SysEx command

The Microcontroller

Arduinos are a series of open source microcontrollers built on an established platform. An individual Arduino device is a simple programmable device that is capable of tasks such as GPIO, but also more advanced communication protocols such as I2C. Makers have the ability of quickly hooking up sensors and other devices to an Arduino and using basic Arduino “sketches” to give instructions to the hardware.

However, devices like an Arduino are fundamentally limited by the single-threaded nature of a microcontroller. Remote Arduino brings together all of the physical control of an Arduino and the supercharged software abilities of Windows devices such as multi-threading, native file systems, simple internet access, and more.

Windows 10

Windows 10 introduces the concept of a Universal Windows Platform (UWP). This means that developers can produce one solution that will work on any device running Windows 10, including Windows Phone 10 and Raspberry Pi 2. By including the Windows Remote Arduino library in your solution, you can turn any Windows device into a remote programming surface for your Arduino! Now it is possible to use the power of the Windows 10 operating system to open up a whole new set of advanced capabilities (and maker projects!) through the use of multi-threading, data storage, internet access, and natural user experiences.

Supported Boards

This section lists boards which have been well-tested using all connection methods offered by this library. If a board or manufacturer is not listed, it does not mean that the board will not work with Windows Remote Arduino, it just means it has not been explicitly tested and verified. In fact, it is the case that most boards will work with this library as long as they can run StandardFirmata or an equivalent sketch that understands the Firmata protocol.

Arduino

  1. Uno
  2. Leonardo
  3. Mega

DFRobot

  1. Bluno
  2. Bluno Beetle

Software Architecture

The implementation is a three layer cake, where each layer provides an entry-point exposed as a Windows Runtime Component. A Maker can choose to use the topmost layer (RemoteWiring) which exposes an interface nearly identical to Arduino Wiring for all basic instructions like GPIO and communication to other devices through I2C. The vast majority of makers will likely never need more. However, a Maker can also choose to interface with the Firmata layer directly for creating advanced behaviors for all of those crazy creative ideas that you are bound to come up with.

Layers

There are three layers in the architecture of Windows Remote Arduino; they are interface, protocol, and transport. Each layer is a consumer of all layers below it, and therefore dependent on them. However, a layer is never dependent on anything above it. The layered construction allows individual layers to be swapped or utilized directly at any time, which provides the ability to supply alternate implementations at each layer. The layers, in their respective ordering, are given below.

  • RemoteWiring (interface)
  • Firmata (protocol)
  • Serial (transport)

For example, the Firmata layer translates the requests of the RemoteWiring layer into the Firmata protocol and then passes them on to the Serial layer for transport to the Arduino (and vise-versa). The Firmata layer has no knowledge of what the Serial implementation looks like, or what method of transport is actually being used. However, the Firmata layer absolutely depends on this layer in order to work. In sharp contrast, the Firmata layer is not aware of the RemoteWiring layer's existence, and therefore could be interacted with directly.

RemoteWiring

The main interface class of the RemoteWiring layer is RemoteDevice, and it is the main API entry point that should be used in most cases. It offers an interface that is nearly identical to what you will find in the Arduino Wiring API, and should therefore be familiar if you have written Arduino sketches yourself. However, It is safe to say that all calls through this layer are directed to the Firmata layer below it, so it is only necessary to bypass or extend this layer when very advanced behaviors are desired for a project!

Firmata

The implementation of Firmata is taken directly from the Firmata repository, with absolute minimal changes (i.e. removing arduino/hardware dependencies), and is wrapped by a transparent Windows Runtime Component library class named UwpFirmata. The wrapper does not change or add functionality, it only provides parameter smoothing (i.e. char * -> String) and paradigm translation (i.e. callbacks -> events). This layer is completely independent from the RemoteWiring layer above it, so it can be used as a fully-functional Firmata implementation!

One advantage UwpFirmata provides through the Windows operating system is the ability to read inputs on a background thread, rather than being constricted to a single thread of execution. In most cases, this thread is created and managed completely by the library. However, if you choose to construct the Firmata layer (UwpFirmata object) yourself, you can choose to enable this feature or not. If your project does not require reading inputs from the Arduino (or if you want to handle them yourself), you may be interested in heading to the advanced usage section for more information!

Serial

Serial is the transport layer, which provides the physical communication between applications and the Arduino device. IStream is the interface which defines the requirements of a communication stream between the Arduino and the application itself. Currently, this is implemented in the default library with the BluetoothSerial class as well as UsbSerial for wired connections on Windows 10 (USB is not supported on Windows 8.1). There are five functions which need to be implemented should you choose to extend the capabilities of the library with other communication methods. These functions MUST be guaranteed to be synchronous operations in order to be consumed by the Firmata layer.

  • begin(int, SerialConfig) -> void -- initializes the stream, the SerialConfig is important when using USB. Default for Arduino is SERIAL_8N1
  • end(void) -> void -- finalizes the stream
  • available(void) -> int -- gets the number of bytes in the stream
  • read(void) -> short -- reads a single character from the incoming stream
  • write(char) -> void -- writes a single character to the outgoing stream

RemoteDevice

A user-friendly wrapper for Firmata, providing an Arduino feel for GPIO and I2C. After adding this package to your solution either manually or through NuGet, you may construct a RemoteDevice object directly.

Setup

This section explains how to set up your Arduino and how to add the Windows Remote Arduino library to your Windows projects!

Arduino Setup

Windows Remote Arduino uses the Firmata protocol, which has implementations in many languages including Arduino! The Arduino implementation is called StandardFirmata and comes pre-packaged with the Arduino software when you install it! The raw StandardFirmata sketch works for USB and Bluetooth, while modified versions are available for WiFi and Ethernet (see below). Follow the steps below to upload the StandardFirmata sketch to your Arduino.

  1. Download and install the Arduino software from http://arduino.cc.
  2. Connect your Arduino device to the computer using USB.
  3. Launch the Arduino application.
  4. Verify that you have the correct Arduino board selected under Tools > Board
  5. Verify that you have the correct COM Port selected under Tools > Port
  6. In the Arduino IDE, navigate to File > Examples > Firmata > StandardFirmata
  7. Verify that StandardFirmata will use the correct baud rate for your connection (see Notes on Serial Commuinication below)
  8. Press “Upload” to deploy the StandardFirmata sketch to the Arduino device.

That’s it! Your Arduino will now run the StandardFirmata sketch forever unless reprogrammed with a different sketch. You can now optionally disconnect your Arduino from the computer and power it in any way you choose. If you wish to use the recommended Bluetooth pairing between your devices, you will need to hook up a Bluetooth device to the Arduino. We recommend the SparkFun Bluetooth Mate Silver.

Notes on Serial Communication

Some hardware setups may require additional considerations when it comes to setting up your Bluetooth device over the serial pins 0 and 1.

  1. Baud Rate: StandardFirmata uses the Serial lines to talk to a Bluetooth device or over USB. By default, it uses a baud rate of 57,600 bps. Depending on the configuration of your Bluetooth device, you may need to modify that rate. It can be found in the setup method and looks like this:

Firmata.begin(57600);

Simply change the begin parameter to match the configuration of your Bluetooth device. The most common configurations are 1152000, 57600, and 9600. The recommended SparkFun Bluetooth Mate devices use 115200 by default. USB connections should also be set to 115200. If you are not sure of the default baud rate of your Bluetooth device, check the device documentation.

  1. Serial vs Serial1: Many Arduino devices, such as the Leonardo and the Yun, use Serial1 (Rather than just Serial) for serial communications over pins 0 and 1. If you are using one of these devices, you will need to change the serial initialization procedure. You will want to remove the line Firmata.begin(57600); and replace it with the code below:
 Serial1.begin( 57600 );	//or your baud rate here, it will be 115200 if using the Bluetooth Mate Silver or Gold
 while( !Serial1 );
 Firmata.begin( Serial1 );

Notes on WiFi and Ethernet

First, you must own an Arduino WiFi shield or an Arduino Ethernet shield.

The Arduino IDE includes WiFi and Ethernet libraries written for their respective shield linked above. Unfortunately, raw StandardFirmata itself doesn't understand these libraries right 'out of the box'. However, custom libraries and Firmata sketches have been written which will allow you to easily configure Windows Remote Arduino to use these shields!

There is an additional repository which contains these libraries and sketches. It is called standard-firmata-networking and is also available as open-source.

  1. Clone the standard-firmata-networking repository.
  2. Copy the EthernetStream and/or WiFiStream folders located in \lib\ to your Arduino libraries directory (usually %HOMEPATH%\Documents\Arduino\libraries)
  3. Open one of the standard-firmata-ethernet.ino or standard-firmata-wifi.ino sketch files.
  4. (WiFi only) customize the WiFi Settings section near the top of the sketch file. This is necessary to connect to your wireless network.
  5. Verify that the correct shield is attached to your Arduino.
  6. Press "Upload" to deploy the Firmata sketch to the Arduino device.

Project Setup

Typically, you will want to add the Windows Remote Arduino library into your own Maker projects. The easiest way to do this is by installing the NuGet package into your projects. NuGet is a quick and easy way to automatically install the packages and setup dependencies. Unfortunately, we do not yet have support for NuGet in Windows 10.

For now, please refer to the manual installation instructions

Usage

This section explains the basic usage of Windows Remote Arduino. This is an excellent place to start if you are new to this library or Arduino Wiring itself. For advanced behaviors, see the advanced readme.

Remote Arduino in 4 Lines

This sample shows how to construct the two necessary objects, an IStream implementation (in this case: BluetoothSerial), and the RemoteDevice. We then add a delegate function to the DeviceReady event on the RemoteDevice which will be called as soon as the device is ready. Last, we call begin() on the IStream object to start the connection process.

C# Example:

        using Microsoft.Maker.RemoteWiring;
        using Microsoft.Maker.Serial;
		
		IStream connection;
		RemoteDevice arduino;

		public void SetupRemoteArduino()
		{
			//create a bluetooth connection and pass it to the RemoteDevice
			//I am using a constructor that accepts a device name or ID.
			connection = new BluetoothSerial( "MyBluetoothDevice" );
			arduino = new RemoteDevice( connection );
			
			//add a callback method (delegate) to be invoked when the device is ready, refer to the Events section for more info
			arduino.DeviceReady += Setup;
			
			//always begin your IStream
			connection.begin( 115200, SerialConfig.SERIAL_8N1 );
		}
		
		//treat this function like "setup()" in an Arduino sketch.
		public void Setup()
		{
			//set digital pin 13 to OUTPUT
			arduino.pinMode( 13, PinMode.OUTPUT );
			
			//set analog pin A0 to ANALOG INPUT
			arduino.pinMode( "A0", PinMode.ANALOG );
		}
		
		//This function will read a value from our ANALOG INPUT pin A0 (range: 0 - 1023) and set pin 13 HIGH if the value is >= 512.
		public void ReadAndReport()
		{
			UInt16 val = arduino.analogRead( "A0" );
			if( val >= 512 )
			{
				arduino.digitalWrite( 13, PinState.HIGH );
			}
			else
			{
				arduino.digitalWrite( 13, PinState.LOW );
			}
		}
C++ Example:
        using namespace Microsoft::Maker::RemoteWiring;
        using namespace Microsoft::Maker::Serial;
		
		IStream ^connection;
		RemoteDevice ^arduino;
		
		public void setupRemoteArduino()
		{
			//create a bluetooth connection and pass it to the RemoteDevice
			connection = ref new BluetoothSerial( "MyBluetoothDevice" );
			arduino = ref new RemoteDevice( connection );
			
			//add a callback method (delegate) to be invoked when the device is ready, refer to the Events section for more info
			arduino->DeviceReady += ref new Microsoft::Maker::RemoteWiring::RemoteDeviceConnectionCallback( this, &MyNamespace::MyClass::setup );
		
			//always begin your IStream
			connection->begin( 115200, SerialConfig::SERIAL_8N1 );
		}

		//treat this function like "setup()" in an Arduino sketch.
		public void setup()
		{
			//set digital pin 13 to OUTPUT
			arduino->pinMode( 13, PinMode::OUTPUT );
			
			//set analog pin A0 to ANALOG INPUT
			arduino->pinMode( "A0", PinMode::ANALOG );
		}
		
		//This function will read a value from our ANALOG INPUT pin A0 (range: 0 - 1023) and set pin 13 HIGH if the value is >= 512.
		public void readAndReport()
		{
			uint16_t val = arduino->analogRead( "A0" );
			if( val >= 512 )
			{
				arduino->digitalWrite( 13, PinState::HIGH );
			}
			else
			{
				arduino->digitalWrite( 13, PinState::LOW );
			}
		}

Working with Analog

Analog input pins (A0, A1, A2, etc) have some unique properties which can cause some confusion working with them for the first time.

These pins support analogRead, but also digital functions like digitalRead and digitalWrite. Therefore, you need to consider the pinMode a little differently than you would in an Arduino IDE.

arduino.pinMode( "A0", PinMode.INPUT ); //sets mode of pin A0 to DIGITAL input. arduino.pinMode( "A0", PinMode.OUTPUT ); //sets mode of pin A0 to DIGITAL output. arduino.pinMode( "A0", PinMode.ANALOG ); //sets mode of pin A0 to ANALOG input.

Therefore, if you want to read analog values from these pins, you must set the pinmode to ANALOG, not simply INPUT or OUTPUT.

Last, when referring to analog pins, make sure to always use strings with the format "A#" (where # is the analog pin number) for the functions pinMode, analogRead, and getPinMode.

arduino.pinMode( "A3", PinMode.ANALOG ); //will correctly set pin A3 to ANALOG INPUT mode. arduino.pinMode( 3, PinMode.ANALOG ); //will do nothing, since pin 3 refers to a digital pin and does not support ANALOG INPUT.

Servo

StandardFirmata includes Servo support, and it works through the analogWrite command. Hook up a servo to your Arduino as usual, set the pin mode on the input pin to PinMode.SERVO and use analogWrite to control the angle!

Here is an example which will sweep a Servo motor back and forth:

public IStream connection;
public RemoteDevice arduino;

public MainPage()
{
    connection = new BluetoothSerial( "myDevice" );	//use the name directly or use BluetoothSerial.listAvailableDevicesAsync to enumerate all devices and provide one in this constructor
    arduino = new RemoteDevice( connection );
    arduino.DeviceReady += OnDeviceReady();
    connection.begin( 115200, SerialConfig.SERIAL_8N1 ); //using my Bluetooth device's baud rate, StandardFirmata configured to match
}

private void OnDeviceReady()
{
	arduino.pinMode( 9, PinMode.SERVO );
	loop();
}

//this async Task function will execute infinitely in the background
private async Task loop()
{
    ushort pos;
	
	while( true )
	{
        for( pos = 0; pos <= 180; pos += 1 ) //sweep from 0 to 180 degrees
        {
            device.analogWrite( 6, pos );
            await Task.Delay( 15 );			//delay 15 ms
        }
	
        for( pos = 180; pos >= 0; pos -= 1 )     //sweep from 180 to 0 degrees
        {
            device.analogWrite( 6, pos );
            await Task.Delay( 15 );
        }
	}
}

Events

As previously mentioned, the RemoteWiring layer allows interactions with the RemoteDevice class to feel like interacting with the device directly through the Wiring API. However, Windows events give us the power to respond immediately to changes reported by the Arduino. Click here for more information about events.

For example, whenever you set an analog or digital pin to INPUT, the library will be notified whenever a pin value changes for digital pins, and every few milliseconds for analog pins. Windows Remote Arduino can pass these notifications on to you in the form of events. Simply subscribe to the event with a delegate function, and that function will automatically be called whenever it is appropriate!

Note:

Events are often called on background threads. You may need to consider basic threading behaviors if you are storing data into an array or object created/used on your main thread, or if you are working with a user interface. When you use digital and analog read, the threading issues are taken care of by the library and are of no concern to you.

IStream connection;
RemoteDevice arduino;

public MyObject()
{
	connection = new BluetoothSerial( "MyBluetoothDevice" ); //Directly providing my device name to connect to
	arduino = new RemoteDevice( connection );

	//subscribe to the ConnectionEstablished event with the name of the function to be called.
	arduino.DeviceReady += MyDeviceReadyCallback;

	//subscribe to the DigitalPinUpdateEvent with the name of the function to be called.
	arduino.DigitalPinUpdated += MyDigitalPinUpdateCallback;
	
	//subscribe to the AnalogPinUpdateEvent with the name of the function to be called.
	arduino.AnalogPinUpdated += MyAnalogPinUpdateCallback;
	
	//always begin your IStream object
	connection.begin( 115200, 0 );
}

//this function will automatically be called when a device connection is established and the device is ready
//you may think of this like setup() in an Arduino sketch. It is the best place to prepare your
//Arduino for the logic that the rest of your program will execute
public void MyDeviceReadyCallback()
{
	//set pin 7 to INPUT mode to automatically receive callbacks when it changes
	arduino.pinMode( 7, PinMode.INPUT );
	
	//set pin 7 to ANALOG mode to automatically receive callbacks when it changes
	arduino.pinMode( "A2", PinMode.ANALOG );
}

//this function will automatically be called whenever a digital pin value changes
public void MyDigitalPinUpdateCallback( byte pin, PinState state )
{
	Debug.WriteLine( "Digital pin " + pin + " is now " + ( state == PinState.HIGH ? "HIGH" + "LOW" ) );
}

//this function will automatically be called whenever the analog values are reported. This is usually every few ms.
public void MyAnalogPinUpdateCallback( byte pin, UInt16 value )
{
	Debug.WriteLine( "Analog pin A" + pin + " is now " + value );
}

Advanced Usage

Please refer to the Advanced Usage documentation.

Notes

For more details, visit MSDN: How to specify device capabilities in a package manifest (Windows Runtime apps).


This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

remote-wiring's People

Contributors

anthony-ngu avatar apdutta avatar bethoma avatar bfjelds avatar connerbrooks avatar devinscoworker avatar frederic34 avatar herrickspencer avatar iotgirl avatar jimaobian avatar manniat avatar marcodiniz avatar mitchdenny avatar mwmckee avatar neilsh-msft avatar ooeygui avatar qijinzhou avatar ras0219-msft avatar smith61 avatar superlime avatar turkycat avatar wldevries avatar zfields avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

remote-wiring's Issues

I2C Reply / Register Reply

When using I2C, aside from the issue of having to request several more bytes than needed, I can't seem to get a response as to what register is responding to the original I2C write command.

For instance, when using the below:

arduino.i2c.beginTransmission(0x40);
arduino.i2c.write(0x1f);
arduino.i2c.endTransmission();

arduino.i2c.requestFrom(0x40, 30);
arduino.i2c.requestFrom(0x40, 30);

I can't seem to actually read what register is replying, though I do get the correct response. The register address always reads as 0. This makes it a bit difficult to process several different requests without creating several callbacks.

If I don't request 30 bytes twice (Even though I only need 2 bytes for the register address), I constantly have to click the button to initiate the request and then it eventually responds. Perhaps it's because of this request for 30 bytes, but I don't know any other way to actually get the I2C to fire off the callback without having to hammer the button to keep asking. (I have a button on the GUI that can be clicked to request the device address of the temp sensor I'm testing)

Is there something I'm still fundamentally missing in regards to I2C? I also tried using a firmata callback, but also receive 0 for the register that's replying. In the above example, I would image 0x1f should be what is represented in the reg_ variable for the callback.

Please advise. Thank you!

Ethernet Example

I'm trying to get the ethernet connection working..

in stdfirmata ethernet I have local IP set as a valid ip for the shield, remote IP I have as the ip for the raspberry pi? (correct way around?) - If I set the remote IP to my PC I can see it attempting to connect on port 3030 (I would have thought the arduino would be the socket server?)

anyway this is the code I am using, is it correct?

    private async Task MicrocontrollerTest()
    {
        Debug.WriteLine("Arduino task running");
        try
        {
            // 192.168.0.55 is the IP assigned in firmata as LocalIP - this correct?
            IStream connection = new NetworkSerial(new HostName("192.168.0.55"), 3030);

            RemoteDevice arduino = new RemoteDevice( connection );

            // Add Handlers for connecton states
            connection.ConnectionEstablished += OnConnectionEstablished;
            connection.ConnectionFailed += OnConnectionFailed;

            // Add handler to configure pins
            arduino.DeviceReady += Setup;

            //subscribe to the DigitalPinUpdateEvent with the name of the function to be called.
            arduino.DigitalPinUpdated += MyDigitalPinUpdateCallback;

            // Params ignored in underlying C++ code.
            connection.begin(115200, SerialConfig.SERIAL_8N1);

        }
        catch (Exception ex)
        {
            Debug.WriteLine("Error " + ex.Message);
            throw;
        }
    }

Feature request: Implement ConfigurableFirmata

I'd like to request the implementation of ConfigurableFirmata which in turn allows us to have a more extendable way of connecting with firmata devices. In my particular use case I want to be able to query OneWire sensors over firmata. ConfigurableFirmata has a OneWire module which can be used to do this.

Would be awesome when the remote-wiring library would include support for ConfigurableFirmata. I made a small attempt at implementing but I'm afraid my C++ knowledge is way too rusty for me to do so effectively. There are existing libraries with support for ConfigurableFirmata available in JavaScript and Ruby, so there's sample code to start from.

See https://github.com/firmata/ConfigurableFirmata

How to use I2C functionality

Hi,

I am trying to implement the BMP280 via i2c with an arduino, which I have connected up as follows and have had working with code native to the arduino and spark, but not via remote arduino:

https://learn.adafruit.com/adafruit-bmp280-barometric-pressure-plus-temperature-sensor-breakout/wiring-and-test

I have found an adafruit BMP280 example for raspberry pi, but haven't been able to get it to work with the remote arduino code.

https://github.com/ms-iot/adafruitsample/tree/master/Lesson_203/FullSolution

I've taken the blinky app which I have working over ethernet with an arduino, and have lifted the BMP280.cs from the adafruit example, and then tried reading the temperature.

I just wondered if you can give me any guidance as to how I can hook this up with the arduino to work via firmata?

Many thanks

Andy

analogRead(string) fails

When I call remDevice.analogRead("A0"); I get an error result.

Debugging the source I found that in Line 132 _analog_offset is added.
For my case this means "A0" - becomes 18
analogRead(18) is called.
And there at line 99 the _analog_offset is added again...

90 uint16_t
91 RemoteDevice::analogRead(
92 uint8_t pin_
93 )
94 {
95 //critical section equivalent to function scope
96 std::lock_guardstd::recursive_mutex lock( _device_mutex );
97

98 uint16_t val = -1;
99 uint8_t analog_pin_num = pin_ + _analog_offset;
100

101 if( _pin_mode[ analog_pin_num ] != static_cast<uint8_t>( PinMode::ANALOG ) )
102 {
103 if( _pin_mode[ analog_pin_num ] == static_cast<uint8_t>( PinMode::INPUT ) )
104 {
105 pinMode( analog_pin_num, PinMode::ANALOG );
106 }
107 else
108 {
109 return static_cast<uint16_t>( val );
110 }
111 }
112

113 if( pin_ < _num_analog_pins )
114 {
115 val = analog_pins[ pin ];
116 }
117

118 return val;
119 }
120

121 uint16_t
122 RemoteDevice::analogRead(
123 Platform::String^ analog_pin_
124 )
125 {
126 uint8_t parsed_pin = parsePinFromAnalogString( analog_pin_ );
127 if( parsed_pin == static_cast<uint8_t>( -1 ) )
128 {
129 return static_cast<uint16_t>( -1 );
130 }
131

132 return analogRead( static_cast<uint8_t>( parsed_pin ) + _analog_offset );
133 }
134

[Firmata] Channel security

As far as I see the communication channel between Arduino and phone is not secure. Could you do something about it? In some scenarios this could be a real pain issue since someone could hack the the communication and control the Arduino from a "spurious" source. Like the first generations TV remotes, the neighbor could control your Arduino.

"AnalogWrite" with incremental delay after using "sendSysex"

I'm getting a strange behavior.

I have this code running in a 50ms loop:
_firmata.sendSysex(0xAA, _buffer.AsBuffer()); _firmata.sendSysex(0xAB, new byte[1].AsBuffer());

Then o call bunches of 'analogWrite' to move a servo;
The first time the servo move instantly, after the secondo bunch of 'analogWrite' the commands start to delay, like it was buffered. The second command bunch delay approximately1 sec, the second 3 secs and go on until theu are taking minutes do got executed.

The breakpoint is hitting 'analogWrite' on the correct time.

If I comment the 'sendSysex' everything run fine

Edit: only occurs on Raspberry, not on my machine

Thanks!

arduino.analogRead() and arduino.digitalRead() cannot work on Leonardo with Firmata

  1. arduino.analogRead() and arduino.digitalRead() cannot work on Leonardo with Firmata
  2. arduino.analogRead() and arduino.digitalRead() can work on UNO with Firmata
  3. The Serial TX LED doesn't blink on Leonardo, which indicates that no data sends from Leonardo to Raspberry Pi.
  4. If running Processing on PC, analogRead() and digitalRead() can work on Leonardo with Firmata.

PC:
Windows 10 RTM
VS Community 2015

Raspberry Pi 2:
Windows 10 IOT RTM

Device:
Arduino Leonardo
Arduino 1.6.4
StandardFirmata

remote-wiring version:
using the latest :
Install-Package Windows-Remote-Arduino

Code:



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 App1
{
    /// <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 timer, timerout;
        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(115200, SerialConfig.SERIAL_8N1);
        }




        private void Timer_Tick(object sender, object e)
        {
            //      arduino.pinMode(2, PinMode.INPUT);
            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;
            }
        }

        private void setUpdate(object sender, object e)
        {
            timerout.Stop();

            System.Diagnostics.Debug.WriteLine("Connection Established");
            timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromMilliseconds(1000);
            timer.Tick += Timer_Tick;
            arduino.pinMode("A0", PinMode.ANALOG);
            arduino.pinMode(LED_PIN, PinMode.OUTPUT);
            timer.Start();
        }

        private void OnConnectionEstablished()
        {
            timerout = new DispatcherTimer();
            timerout.Tick += setUpdate;
            timerout.Interval = TimeSpan.FromMilliseconds(10000);
            timerout.Start();

        }


    }
}



Pin configuration not received

Hi,

I am testing "sendSysex" function between windows phone 8.1 and arduino (with SparkFun Bluetooth Mate Silver). the connection can be established successfully, but I got below error message when executing "sendSysex" to turn on/off LED (https://github.com/ms-iot/remote-wiring/blob/develop/advanced.md).

Arduino Failed: A device connection was established, but the device failed handshaking procedures. Verify that your device is configured with StandardFirmata. Message: Catastrophic failure
Pin configuration not received.

(StandardFirmata version: 2.5)

Only works with 'OldStandardFirmata'

It seems the library only works when you flash an Arduino with the 'OldStandardFirmata'
sketch. When you flash the StandardFirmata it connects fine, but nothing happens. It would be wise to add this to the documentation or better yet support the new standard sketch.

I haven't dug deeper, but this was using the https://github.com/ms-iot/windows-remote-arduino-samples project with an Arduino Uno with a BlueSmirf Silver connected to a Surface Pro 3 running Win 8.1 pro.

[Serial] COM Exception

First-chance exception at 0x777059A3 in RomeoTester.exe: Microsoft C++ exception: Platform::COMException ^ at memory location 0x03DEFAF8. HRESULT:0x8000000E A method was called at an unexpected time.

WinRT information: A method was called at an unexpected time.

Stack trace:
Microsoft.Maker.Serial.WindowsPhone.dll!Microsoft::Maker::Serial::BluetoothSerial::[Microsoft::Maker::Serial::IStream]::read() Line 184
_current_load_operation->Status != Windows::Foundation::AsyncStatus::Started

Microsoft.Maker.Firmata.WindowsPhone.dll!FirmataClass::processInput() Line 230
unsigned short inputData = FirmataStream->read();

Microsoft.Maker.Firmata.WindowsPhone.dll!Microsoft::Maker::Firmata::UwpFirmata::inputThread() Line 402
::RawFirmata.processInput();

Microsoft.Maker.Firmata.WindowsPhone.dll!Microsoft::Maker::Firmata::UwpFirmata::startListening::__l5::() Line 89
_inputThread = std::thread( [ this ]() -> void { inputThread(); } );

If there is a handler for this exception, the program may be safely continued.

unable to write or read data from arduino

I am using arduino uno and i am able to connect to arduino via bluetooth but I am un able to read or write data to the device... Pls help.. I have tried changing the TX RX of bluetooth with aurdino both ways... My bound rate is 57600 in firmata and bluethooth....

[Serial] Multiple Bluetooth Connection Supported?

The scenario is…

  • There is one Windows 10 IoT Raspberry Pi gateway
  • Two Arduino UNO devices connected with gateway, where Gateway controls them via using “Windows Remote Arduino” especially reading the sensor value connected with both Arduino.
  •    The communication between Gateway and other devices (slaves) is via Bluetooth. 
    
  • Gateway is controlling the both Arduino via Windows Remote Arduino using “Firmata”.

Now, problem is, even though I'm making two different Bluetooth connection with Arduino from Raspberry Pi, still only one able to read the sensor/Arduino value?
So, seems like there is issue when making multiple connection? Isn't is supported scenarios/what? Please help.

Added DF Robot BLE Serial

I'm trying to use this but no luck. The DfRobot forum tells me that the Bluno will only talk to their own gear and app.. but I guess that the inclusion of DfRBLE here suggests that it can be done.

Do you have an example please ? I can't see the Bluno through the sample code or through the Remote Arduino Experience App :(

DigitalPinUpdated Callback not working?

I've now got the device communicating over ethernet, but I seem unable to get the DigitalPin Callback events to work, analog works ok, but is getting fired a lot

If I use remote commander from my tablet I can see the values change on the digital input pin (7)

Is this a known issue (i'm using arduino uno boards (possibly a clone - but works in remote commander so I dont think its that.)

[Serial] Refactor `begin()` method

Remove the random select (default constructor), then the flow becomes greatly simplified.

if (_deviceName) {
    listAvailableDevicesAsync();
    indentifyDeviceFromCollection();
}
connectToDeviceAsync();

Access Violation with USB connection on Raspberry Pi 2

Hi,

I am trying to get a connection to my Arduino Micro with the UsbSerial solution but I keep getting 'Access Violation' errors after initialization. I use a Raspberry Pi 2 for running the code.

Below the code where it fails, I edited the sample code just a bit.

The code fails a half second after the Connection Established breakpoint is hit when the 'usb.begin(57600, SerialConfig.SERIAL_8N1)' code is called. It does not throw any exceptions and kills the app + debug session.

usbserial

Side info:
My Raspberry Pi 2 is on OS version '10.0.10152.0'.
Works smoothly on as Windows 10 desktop app (build: 10158).

Greetings,
Mark Hijdra

WiFi handshake failure

Hi,
I'm using a Arduino/Genino MKR1000 board with the Windows Remote Arduino Experience App.
After uploading the StandardFirmata sketch to the board, Windows Remote Arduino Experience
connects to the board without any problems, both USB and Bluetooth connetctions work fine.
Now when running the StandardFirmataWiFi sketch on the board, Windows Remote Arduino Experience fails to
connect with the following Error Message :

"Connection attempt failed. A device connection was established, but the device failed handshaking procedures.
Verifiy that your device is configured with StandardFirmata. Message : Catastrophic Failure Pin configuration
not received."

I'm using version 1.6.9 of the Arduino ide.
Firmata Library v 2.5.2
WiFi101 v 0.9.1

(Enabling the Serial Monitor when running StandardFirmataWiFi shows no problems, an ip-address is obtained
so the board is connected to the network)

Any ideas what the problem might be ?

NuGet Packages for Windows 10

Hi there,
Are there any plans to release official NuGet packages for the libraries in this repository? I think it would make it significantly easier for folks to just pick up and run with these components.

Guidance on disconnecting

Hi there, I'm going to crosspost this from https://social.msdn.microsoft.com/Forums/en-US/7728b0f0-2842-4da8-add5-950b11847417/best-practices-for-connecting-disconnecting-bluetooth-devices?forum=WindowsIoT, hoping to get some more info here.

I'm looking for some best practice guidance on connecting and in particular disconnecting bluetooth devices. The connecting part is all and well, working and everything. But I want to make my app (running on Raspberry Pi) resilient to connection failures too. When the connection to a bluetooth device is lost for whatever reason, I have some logic which tries to re-establish the connection using the same code that's used to set it up initially. Unfortunately that doesn't seem to work and I'm not sure how to improve it.

I'm using classes of the following types:

  • DeviceInformation - which I get for my two paired blueooth devices.
  • BluetoothSerial - (from Microsoft.Maker.Serial), for serial communication
  • UwpFirmata - (from Microsoft.Maker.Firmata), to implement the Firmata protocol
  • RemoteDevice - for interacting with the actual device (Arduino btw)

So what I'm looking for is: which classes do I dispose / make null / recreate, which do I maybe reuse? What methods should I use for reconnecting cause obviously my current attempts just recreating everything are not the way to go. I also tried disposing everything, which ended in internal exceptions being fired (sorry, don't have any stacktrace at the moment). I should note that that was a couple of builds ago, so I could retry it and see whether things have improved over time.

I'm also seeing some weird behavior connecting and disconnecting devices. Sometimes my app will crash (mostly just bugs in my software, don't worry). If I now restart the app, in some occasions Windows has lost the DeviceInfo object for one of my paired bluetooth devices. I use the following code to query the device registry:

DeviceInformation.FindAllAsync(RfcommDeviceService.GetDeviceSelector(RfcommServiceId.SerialPort))

Normally, this method returns two objects of type DeviceInfo. But when this behavior occurs, it will return only one. Now one might think the other device is in some sort of locked state which was not freed because the app crashed. I would agree, but even after restarting this issue still persists. Btw same happens when I exit the app from Visual Studio.

The only workaround I have at the moment it to unpair the device and pair again via the web interface. After re-pairing, above method returns two items again. So still on the look-out for some good advise on how to handle these connections! :)

Reading from Arduino only after 99 bytes received

Hello All,

I am building an App using custom SysEx commands but before implementing the new SysEx I am testing using StandardFirmata just sending REPORT_FIRMWARE (0x79) SysEx and checking the answer.

I have to send 2-3 time the SysEx to get the answer. After trying and investigating deeper, I saw that remote-wiring only reads the input buffer when there is 99 bytes in the buffer.

Is that the normal behavior?

Is there a way to read byte from serial as they come?

I am using a Win10 and a Arduino UNO with StandardFirmata sketch.

Thanks in advance,

Paulo Henrique (nambuco)

Arduino AnalogRead with a LM35 temp sensor - Always returns 65535

I've got an Arduino successfully connected and the RemoteBlinky app working. I've setup the Arduino A0 pin with arduino.pinMode("A0", PinMode.ANALOG); and i'm reading it with UInt16 rawTemp = arduino.analogRead("A0"); but rawTemp is always 65530.

The LM35 is connected to 5V, GND and A0 on the Arduino (this setup works correctly using the sample Arduino sketch.) Using my DMM I can see the chip is correctly putting out 0.2V to the A0 pin.

Anyone have any idea whats going on? Thanks!

Can not NuGet on Windows 8.1

Hello,
working on Windows 8.1 and a Windows 8.1 universal app, deploying the NuGet Package yields the error:
Attempting to gather dependencies information for package 'Windows-Remote-Arduino.1.3.0' with respect to project 'SUSArduino1\SUSArduino1.Windows', targeting 'Windows,Version=v8.1'
Attempting to resolve dependencies for package 'Windows-Remote-Arduino.1.3.0' with DependencyBehavior 'Lowest'
Resolving actions to install package 'Windows-Remote-Arduino.1.3.0'
Resolved actions to install package 'Windows-Remote-Arduino.1.3.0'
Install failed. Rolling back...
Package 'Windows-Remote-Arduino.1.3.0 : ' does not exist in project 'SUSArduino1.Windows'
Package 'Windows-Remote-Arduino.1.3.0 : ' does not exist in folder 'C:\Users\TAMHAN\Desktop\SUSArduinoWin\SUSArduino1\packages'
Could not install package 'Windows-Remote-Arduino 1.3.0'. You are trying to install this package into a project that targets 'Windows,Version=v8.1', but the package does not contain any assembly references or content files that are compatible with that framework. For more information, contact the package author.
========== Finished ==========

Please remedy!

With compliments
Tam HANNA

CAPABILITY_QUERY is sent many times by BleSerial

When using BleSerial, CAPABIRITY_QUERY is sent many times on connection.
It takes about 300 to 400 milliseconds for BLE to be connected from pairing, but the retransmission interval is shorter than that.

const int MAX_ATTEMPTS = 30; const int MAX_DELAY_LOOP = 5; const int INIT_DELAY_MS = 10;

UsbSerial.Read outputs randomly crap

I'm wondering if there's something wrong with my code or the UsbSerial.Read -function, as I have problem that it outputs crap randomly messing my output. I have tried different baud rates as well, with the same problem.

I'm creating the connection like this:
connection = new UsbSerial(selected);
connection.ConnectionEstablished += Connection_ConnectionEstablished; ;
connection.begin(9600, SerialConfig.SERIAL_8N1);

and in the connectionEstablished I'm reading the serial like this:

while (true)
{
Debug.Write(Convert.ToChar(connection.read()));
}

My Arduino code writes in a loop 1234567890 and that's how the output shows in Putty for example, but in Visual Studio debug output I can see that it does this every 5-8 line:1�234567980

Any pointers if I'm doing something wrongly?

[Serial] Remove unnecessary member variables

We are keeping state for no reason (mostly begin() method); racks up unnecessary memory.

For example:
Windows::Devices::Bluetooth::Rfcomm::RfcommDeviceService ^_device_service;
Windows::Devices::Bluetooth::Rfcomm::RfcommServiceId ^_service_id;
Windows::Devices::Bluetooth::Rfcomm::RfcommServiceProvider ^_service_provider;
Windows::Networking::Sockets::StreamSocket ^_stream_socket;

Digital pin updated REAL slow to report?

I've been trying to figure out what it the issue here but haven't be able to nail it down.

Symptom:
Waiting for digital pin update event is talking a long time or queuing up several updates before it finally bursts through all the pin updates that had happened.

Setup:

  • Arduino UNO (also tried on a YUN) attached via USB, with StandardFirmata 2.5.2, tried with 2.4 as well
  • Windows 10 running on my 64-bit laptop
  • Button hooked up to a digital pin (5 in my test case)

Repo Steps:
In any Win 10 sample app (even the Remote Experience sample) set a pin to INPUT (or PULLUP if you use my fork -- see my PR --).

Capture the DigitalPinUpdated event.

Wire a button (or even a jumper cable straight to 5v [input mode] or GND [pullup mode]) as appropriate for the pin mode.

Run the app, hit the button/jumper one time, verified the Tx light lit-up on my UNO when the state transitioned. I see no output from the DigitalPinUpdated event.

Wait for a while, nothing seems to come through.

Hit the button/jumper a bunch of times and eventually I get a burst of updates from the event.

What I tried/looked at:

  1. First, I verified this exact scenario works fine using an equivalent Johnny-Five program.
  2. I put breakpoints within RemoteDevice's OnDigitalReport() and it is getting called in the same manner as above
  3. Walking back to Firmata I can see that processInput is properly looping
  4. Started looking into UsbSerial but not familiar enough with the code [read() method] to determine a cause
  5. Tried compiling in x86 or x64 ... just in case ;) Same issue.

Analog Pin Configuration Issue

arduino.pinMode("A0", PinMode.ANALOG); produces an unhandled exception of type 'System.AccessViolationException' in the below code.

public sealed partial class MainPage : Page
{
UsbSerial connection;
RemoteDevice arduino;

    public MainPage()
    {
        connection = new UsbSerial("VID_2A03", "PID_0043");
        arduino = new RemoteDevice(connection);
        connection.ConnectionEstablished += OnConnectionEstablished;
        connection.begin(57600, SerialConfig.SERIAL_8N1);
        this.InitializeComponent();
    }

    private void OnConnectionEstablished()
    {
        arduino.pinMode("A0", PinMode.ANALOG);
        arduino.pinMode("A1", PinMode.ANALOG);
        arduino.AnalogPinUpdated += Arduino_AnalogPinUpdated;
    }

This code was working but with the latest update the above exception is now produced. Is there a different requirement for setting the analog pins?
Thank you!

[Firmata] "sendSysex" doesn't work properly

I followed this tutorial https://github.com/ms-iot/remote-wiring/blob/develop/advanced.md to setup a very simple custom command. "FirmataConnectionReady" works properly when initializing Firmata the first time, but Firmata.sendSysex doesn't work when sending custom command. below are the codes:

On Arduino Side - >

define ALL_PINS_COMMAND 0x42

void sysexCallback(byte command, byte argc, byte *argv)
{
byte mode;
byte slaveAddress;
byte data;
int slaveRegister;
unsigned int delayTime;

switch (command) {
case ALL_PINS_COMMAND:
Firmata.sendString("Hello from arduino!");
break;
... ...
...

C# Side - >

const byte ALL_PINS_COMMAND = 0x42;
... ...
public void SendSysexCommandHandler(object arg)
{
if(Firmata.connectionReady()) <----------- return true
{
byte b = 1;
Firmata.sendSysex(ALL_PINS_COMMAND, new byte[] { b }.AsBuffer());
}
}

Code not working in Visual Basic 2015

I am trying to get Windows-Remote-Arduino working in a Visual Basic 2015 Universal application.

I got it to work all right with this C# code:
connection.ConnectionEstablished += OnConnectionEstablished;
connection.begin(115200, SerialConfig.SERIAL_8N1);

In VB, when I type in connection. the options that appear are: available, begin, connectionReady, etc.

None of them seem to work.

I am trying to figure out the code to make this work.
What option is similar to ConnectionEstablished?

Thanks.

[Firmata] Smart delay when `0xFFFF` is received from `read()`

Reduce the polling frequency on the processInput() reader thread when no data is available to read; perhaps using a back-off algorithm.

In a simple example, have no delay if the last read was successful, but have an incremental delay as each successive read fails (i.e 1ms, 2ms, 4ms, 8ms, 16ms, 32ms, 64ms, 128ms, 128ms, 128ms, etc.).

A slightly more sophisticated example would be to keep a last successful read timestamp, then use a logarithmic function to generate a "time-to-delay" curve based on the time passed since last successful read.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.