Giter Club home page Giter Club logo

Comments (16)

spaniakos avatar spaniakos commented on August 26, 2024

Can u show us some come ? Sometimes there is something not related to the
library.

from rf24network.

Onmt39 avatar Onmt39 commented on August 26, 2024

arduino code.

(deleted the SPI RF24 and RF24Network includes)
RF24 radio(9,10);
RF24Network network(radio);

const uint16_t master = 00;
const uint16_t stem_a = 01;
const uint16_t stem_b = 02;
const uint16_t stem_c = 03;
const uint16_t stem_d = 04;
const uint16_t stem_e = 05;
const uint16_t leaf_aa = 011;

const uint16_t this_node = stem_a;
const uint16_t default_out_address = master;

byte out_payload;
byte out_address;
byte in_payload;
byte in_address;
bool counter_talk = 1;
bool counter_rest = 0;

bool previous_eight;
bool eight;
bool previous_seven;
bool seven;
bool previous_six;
bool six;
bool previous_five;
bool five;
unsigned char light_green = A5;
unsigned char light_blue = A3;
long previousMillis = 0;
long light_time = 1;
bool light_blue_engage;
bool light_green_engage;

void setup(void) {

pinMode(8,INPUT_PULLUP);
pinMode(7,INPUT_PULLUP);
pinMode(6,INPUT_PULLUP);
pinMode(5,INPUT_PULLUP);

pinMode(A4,OUTPUT);
pinMode(A2,OUTPUT);
pinMode(light_blue,OUTPUT);
pinMode(light_green,OUTPUT);
digitalWrite(A4,LOW);
digitalWrite(A2,LOW);
digitalWrite(light_green,LOW);
digitalWrite(light_blue,LOW);

unsigned long currentMillis = millis();
SPI.begin();
radio.begin();
network.begin(90,this_node);
Serial.begin(57600);
delay(3);
Serial.print("address = ");
Serial.println(this_node);
}

void loop() {
network.update();
unsigned long currentMillis = millis();
check_input_states();
if(network.available()) {
RF_in(); }

if((currentMillis - previousMillis) > light_time) {
if(light_blue_engage == 1) {
//Serial.print("..off..");
digitalWrite(light_blue,LOW);
light_blue_engage = 0; }
if(light_green_engage == 1) {
//Serial.print("..off..");
digitalWrite(light_green,LOW);
light_green_engage = 0; }
previousMillis = currentMillis; }
}

void RF_in() {
RF24NetworkHeader header;
network.read(header,&in_payload,sizeof(in_payload));
digitalWrite(light_green, HIGH);
light_green_engage = 1;
if(in_payload == 255) {
sleep(); }
Serial.print("payload is ");
Serial.println(in_payload);
Serial.print(" from <");
Serial.print(header.from_node);
Serial.println(">..");
}

void RF_out(byte message, byte to) {
Serial.print("Sending..");
RF24NetworkHeader header(to);
bool ok = network.write(header,&message,sizeof(message));
Serial.print("<");
Serial.print(message);
Serial.print(">");
Serial.print("...TO...<");
Serial.print(to);
Serial.print(">");
if (ok) {
digitalWrite(light_blue,HIGH);
light_blue_engage = 1;
Serial.println("..ok."); }
else {
Serial.println("..failed."); }
}

//bool light_blue_on() {
//digitalWrite(light_blue, HIGH);
//return 1;

//}

void sleep() {
bool sleep = 1;
Serial.println("zzz...");
while (sleep) {
network.update();
if(network.available()) {
RF24NetworkHeader header;
network.read(header,&in_payload,sizeof(in_payload));
if(in_payload == 254) {
sleep = 0;
Serial.println("waking...");} } }
}

void check_input_states() {
eight = digitalRead(8);
seven = digitalRead(7);
six = digitalRead(6);
five = digitalRead(5);
if(eight != previous_eight) {
if(eight == 0) {
RF_out(81, default_out_address); }
if(eight == 1) {
RF_out(80, default_out_address); }
previous_eight = eight; }

if(seven != previous_seven) {
if(seven == 0) {
RF_out(71, default_out_address); }
if(seven == 1) {
RF_out(70, default_out_address); }
previous_seven = seven; }

if(six != previous_six) {
if(six == 0) {
RF_out(61, default_out_address); }
if(six == 1) {
RF_out(60, default_out_address); }
previous_six = six; }

if(five != previous_five) {
if(five == 0) {
RF_out(51, default_out_address); }
if(five == 1) {
RF_out(50, default_out_address); }
previous_five = five; }
}

RPi code (python)

#!/usr/bin/env python

import time
from struct import *
from RF24 import *
from RF24Network import *

network = RF24Network(radio)

this_node = 00

other_node = 01

interval = 2000 #ms - How often to send 'hello world' to the other unit

millis = lambda: int(round(time.time() * 1000))

radio.begin()
time.sleep(0.1)
network.begin(90, this_node) # channel 90
radio.printDetails()
packets_sent = 0
last_sent = 0

while 1:
network.update()
while network.available():
header, payload = network.read(12)
ms, number = unpack('<qi', payload)
print 'Received payload # ', number, ' at ', ms, ' from ', oct(header.from_node)
#time.sleep(1)

RPi (c)

/*
Update 2014 - TMRh20
*/

/**

  • Simplest possible example of using RF24Network,
    *
  • RECEIVER NODE
  • Listens for messages from the transmitter and prints them out.
    */

#include
#include
#include <RF24/RF24.h>
#include <RF24Network/RF24Network.h>
#include
#include <stdio.h>
#include <time.h>

/**

  • g++ -L/usr/lib main.cc -I/usr/include -o main -lrrd
    **/
    //using namespace std;

// CE Pin, CSN Pin, SPI Speed

// Setup for GPIO 22 CE and GPIO 25 CSN with SPI Speed @ 1Mhz
//RF24 radio(RPI_V2_GPIO_P1_22, RPI_V2_GPIO_P1_18, BCM2835_SPI_SPEED_1MHZ);

// Setup for GPIO 22 CE and CE0 CSN with SPI Speed @ 4Mhz
//RF24 radio(RPI_V2_GPIO_P1_15, BCM2835_SPI_CS0, BCM2835_SPI_SPEED_4MHZ);

// Setup for GPIO 22 CE and CE1 CSN with SPI Speed @ 8Mhz
RF24 radio(RPI_V2_GPIO_P1_15, BCM2835_SPI_CS0, BCM2835_SPI_SPEED_8MHZ);

RF24Network network(radio);

const uint16_t master = 00;
const uint16_t stem_a = 01;
const uint16_t stem_b = 02;
const uint16_t stem_c = 03;
const uint16_t stem_d = 04;
const uint16_t stem_e = 05;
const uint16_t leaf_aa = 011;

const uint16_t this_node = master;
const uint16_t default_out_address = stem_a;

unsigned char out_payload;
unsigned char out_address;
unsigned in_payload;
unsigned char in_address;
bool counter_talk = 1;
bool counter_rest = 0;

const unsigned long interval = 2000; //ms // How often to send 'hello world to the other unit

unsigned long last_sent; // When did we last send?
unsigned long packets_sent; // How many have we sent already

struct payload_t { // Structure of our payload
unsigned char in_payload;
};

void RF_in() {
RF24NetworkHeader header;
network.read(header,&in_payload,sizeof(in_payload));
//if(in_payload == 255) {
//sleep(); }
//printf("payload is");
printf("%u\n", in_payload);
//printf("Received payload # %lu at %lu \n");
}

int main(void)//int argc, char** argv)
//void main(void)
{
// Refer to RF24.h or nRF24L01 DS for settings

radio.begin();

delay(5);
network.begin(/*channel*/ 90, /*node address*/ this_node);
radio.printDetails();

while(1)
{

    network.update();
    while ( network.available() ) {     // Is there anything ready for us?
        RF_in();

        //printf("Received payload # %lu at %lu \n");

}
//sleep(2);
//fclose(pFile);
}

return 0;

}

from rf24network.

spaniakos avatar spaniakos commented on August 26, 2024

I can't see something that will define the problem .
I don't know if I have time to test it today as I am not near my equipment,
but will test it on no Monday with an rpi and Intel Galileo
On Nov 28, 2014 10:54 AM, "Onmt39" [email protected] wrote:

arduino code.

#include
#include
#include
RF24 radio(9,10);
RF24Network network(radio);

const uint16_t master = 00;
const uint16_t stem_a = 01;
const uint16_t stem_b = 02;
const uint16_t stem_c = 03;
const uint16_t stem_d = 04;
const uint16_t stem_e = 05;
const uint16_t leaf_aa = 011;

const uint16_t this_node = stem_a;
const uint16_t default_out_address = master;

byte out_payload;
byte out_address;
byte in_payload;
byte in_address;
bool counter_talk = 1;
bool counter_rest = 0;

bool previous_eight;
bool eight;
bool previous_seven;
bool seven;
bool previous_six;
bool six;
bool previous_five;
bool five;
unsigned char light_green = A5;
unsigned char light_blue = A3;
long previousMillis = 0;
long light_time = 1;
bool light_blue_engage;
bool light_green_engage;

void setup(void) {

pinMode(8,INPUT_PULLUP);
pinMode(7,INPUT_PULLUP);
pinMode(6,INPUT_PULLUP);
pinMode(5,INPUT_PULLUP);

pinMode(A4,OUTPUT);
pinMode(A2,OUTPUT);
pinMode(light_blue,OUTPUT);
pinMode(light_green,OUTPUT);
digitalWrite(A4,LOW);
digitalWrite(A2,LOW);
digitalWrite(light_green,LOW);
digitalWrite(light_blue,LOW);

unsigned long currentMillis = millis();
SPI.begin();
radio.begin();
network.begin(90,this_node);
Serial.begin(57600);
delay(3);
Serial.print("address = ");
Serial.println(this_node);
}

void loop() {
network.update();
unsigned long currentMillis = millis();
check_input_states();
if(network.available()) {
RF_in(); }

if((currentMillis - previousMillis) > light_time) {
if(light_blue_engage == 1) {
//Serial.print("..off..");
digitalWrite(light_blue,LOW);
light_blue_engage = 0; }
if(light_green_engage == 1) {
//Serial.print("..off..");
digitalWrite(light_green,LOW);
light_green_engage = 0; }
previousMillis = currentMillis; }
}

void RF_in() {
RF24NetworkHeader header;
network.read(header,&in_payload,sizeof(in_payload));
digitalWrite(light_green, HIGH);
light_green_engage = 1;
if(in_payload == 255) {
sleep(); }
Serial.print("payload is ");
Serial.println(in_payload);
Serial.print(" from <");
Serial.print(header.from_node);
Serial.println(">..");
}

void RF_out(byte message, byte to) {
Serial.print("Sending..");
RF24NetworkHeader header(to);
bool ok = network.write(header,&message,sizeof(message));
Serial.print("<");
Serial.print(message);
Serial.print(">");
Serial.print("...TO...<");
Serial.print(to);
Serial.print(">");
if (ok) {
digitalWrite(light_blue,HIGH);
light_blue_engage = 1;
Serial.println("..ok."); }
else {
Serial.println("..failed."); }
}

//bool light_blue_on() {
//digitalWrite(light_blue, HIGH);
//return 1;

//}

void sleep() {
bool sleep = 1;
Serial.println("zzz...");
while (sleep) {
network.update();
if(network.available()) {
RF24NetworkHeader header;
network.read(header,&in_payload,sizeof(in_payload));
if(in_payload == 254) {
sleep = 0;
Serial.println("waking...");} } }
}

void check_input_states() {
eight = digitalRead(8);
seven = digitalRead(7);
six = digitalRead(6);
five = digitalRead(5);
if(eight != previous_eight) {
if(eight == 0) {
RF_out(81, default_out_address); }
if(eight == 1) {
RF_out(80, default_out_address); }
previous_eight = eight; }

if(seven != previous_seven) {
if(seven == 0) {
RF_out(71, default_out_address); }
if(seven == 1) {
RF_out(70, default_out_address); }
previous_seven = seven; }

if(six != previous_six) {
if(six == 0) {
RF_out(61, default_out_address); }
if(six == 1) {
RF_out(60, default_out_address); }
previous_six = six; }

if(five != previous_five) {
if(five == 0) {
RF_out(51, default_out_address); }
if(five == 1) {
RF_out(50, default_out_address); }
previous_five = five; }
}

RPi code (python)

#!/usr/bin/env python

Simplest possible example of using RF24Network,

RECEIVER NODE Listens for messages from the transmitter and prints them
out.

import time
from struct import *
from RF24 import *
from RF24Network import *
CE Pin, CSN Pin, SPI Speed Setup for GPIO 22 CE and GPIO 25 CSN with SPI
Speed @ 1Mhz

#radio = radio(RPI_V2_GPIO_P1_22, RPI_V2_GPIO_P1_18,
BCM2835_SPI_SPEED_1MHZ)
Setup for GPIO 22 CE and CE0 CSN with SPI Speed @ 4Mhz

#radio = RF24(RPI_V2_GPIO_P1_15, BCM2835_SPI_CS0, BCM2835_SPI_SPEED_4MHZ)
Setup for GPIO 22 CE and CE1 CSN with SPI Speed @ 8Mhz

#radio = RF24(RPI_V2_GPIO_P1_15, BCM2835_SPI_CS0, BCM2835_SPI_SPEED_8MHZ)
Setup for GPIO 22 CE and CE0 CSN for RPi B+ with SPI Speed @ 8Mhz

radio = RF24(RPI_BPLUS_GPIO_J8_22, RPI_BPLUS_GPIO_J8_24,
BCM2835_SPI_SPEED_8MHZ)

network = RF24Network(radio)
Address of our node in Octal format (01,021, etc)

this_node = 00
Address of the other node

other_node = 01

interval = 2000 #ms - How often to send 'hello world' to the other unit

millis = lambda: int(round(time.time() * 1000))

radio.begin()
time.sleep(0.1)
network.begin(90, this_node) # channel 90
radio.printDetails()
packets_sent = 0
last_sent = 0

while 1:
network.update()
while network.available():
header, payload = network.read(12)
ms, number = unpack('<qi', payload)
print 'Received payload # ', number, ' at ', ms, ' from ',
oct(header.from_node)
#time.sleep(1)

RPi (c)

/*
Update 2014 - TMRh20
*/

/**

  • Simplest possible example of using RF24Network, *
  • RECEIVER NODE
  • Listens for messages from the transmitter and prints them out. */

#include
#include
#include
#include
#include
#include
#include

/**

  • g++ -L/usr/lib main.cc -I/usr/include -o main -lrrd **/ //using
    namespace std;

// CE Pin, CSN Pin, SPI Speed

// Setup for GPIO 22 CE and GPIO 25 CSN with SPI Speed @ 1Mhz
//RF24 radio(RPI_V2_GPIO_P1_22, RPI_V2_GPIO_P1_18, BCM2835_SPI_SPEED_1MHZ);

// Setup for GPIO 22 CE and CE0 CSN with SPI Speed @ 4Mhz
//RF24 radio(RPI_V2_GPIO_P1_15, BCM2835_SPI_CS0, BCM2835_SPI_SPEED_4MHZ);

// Setup for GPIO 22 CE and CE1 CSN with SPI Speed @ 8Mhz
RF24 radio(RPI_V2_GPIO_P1_15, BCM2835_SPI_CS0, BCM2835_SPI_SPEED_8MHZ);

RF24Network network(radio);

const uint16_t master = 00;
const uint16_t stem_a = 01;
const uint16_t stem_b = 02;
const uint16_t stem_c = 03;
const uint16_t stem_d = 04;
const uint16_t stem_e = 05;
const uint16_t leaf_aa = 011;

const uint16_t this_node = master;
const uint16_t default_out_address = stem_a;

unsigned char out_payload;
unsigned char out_address;
unsigned in_payload;
unsigned char in_address;
bool counter_talk = 1;
bool counter_rest = 0;

const unsigned long interval = 2000; //ms // How often to send 'hello
world to the other unit

unsigned long last_sent; // When did we last send?
unsigned long packets_sent; // How many have we sent already

struct payload_t { // Structure of our payload
unsigned char in_payload;
};

void RF_in() {
RF24NetworkHeader header;
network.read(header,&in_payload,sizeof(in_payload));
//if(in_payload == 255) {
//sleep(); }
//printf("payload is");
printf("%u\n", in_payload);
//printf("Received payload # %lu at %lu \n");
}

int main(void)//int argc, char** argv)
//void main(void)
{
// Refer to RF24.h or nRF24L01 DS for settings

radio.begin();

delay(5);
network.begin(/channel/ 90, /node address/ this_node);
radio.printDetails();

while(1)
{

network.update();
while ( network.available() ) {     // Is there anything ready for us?
    RF_in();

    //printf("Received payload # %lu at %lu \n");

}

//sleep(2);
//fclose(pFile);
}

return 0;

}


Reply to this email directly or view it on GitHub
#29 (comment).

from rf24network.

Onmt39 avatar Onmt39 commented on August 26, 2024

ok thanks, is there a way i can insert code because its hard to read?

from rf24network.

spaniakos avatar spaniakos commented on August 26, 2024

What u mean insert code ?
If u mean just for the tests u can send them to my Email.
[email protected]
On Nov 28, 2014 11:05 AM, "Onmt39" [email protected] wrote:

ok thanks, is there a way i can insert code because its hard to read?


Reply to this email directly or view it on GitHub
#29 (comment).

from rf24network.

TMRh20 avatar TMRh20 commented on August 26, 2024

"I've released that the arduino still believes that the message was received two or three transmissions after I've stopped the RPi program"

The RPi is not even sending anything in the code you posted. It also looks like the arduino is sending data very rapidly. The radios have three 32-byte buffers, so if you fill them up, it will take three reads to empty them.

See https://help.github.com/articles/github-flavored-markdown/#fenced-code-blocks for help inserting code.

from rf24network.

Onmt39 avatar Onmt39 commented on August 26, 2024

What I meant by that statement was the arduino stated the message was received by the RPi when testing the bool statement (bool ok = network.write(header,&message,sizeof(message));).

If its the radios that have the 3 32-byte buffers why doesn't this happen when sending to another arduino? Sorry if it doesn't make sense Im still learning and don't understand everything.

from rf24network.

TMRh20 avatar TMRh20 commented on August 26, 2024

Well, you can't really 'stop the program' on an Arduino, you can only power it off, along with the radio.

Example:

  1. RPI is running, radio is on.
  2. RPI program stops, but radio is still running with the same configuration
  3. Arduino sends three more payloads, and the radio automatically sends an auto-ack (requires no action by the RPI). It now has 3 payloads in the FIFO buffers.
  4. Arduino is running, radio is on
  5. Arduino is powered off, as is the radio
  6. Arduino sends more payloads, but the radio is off, so does not acknowledge them

Test to prove if this is the case or not:

  1. On RPi, set the last line to radio.powerDown(); or radio.stopListening() before exiting the application
  2. The RPi should not acknowledge any received payloads after the program stops

from rf24network.

Onmt39 avatar Onmt39 commented on August 26, 2024

Thank you, the RPi doesn't acknowledge any received payloads when radio.stopListening() or radio.powerDown() is used. I'll use that before exiting.

Earlier you said " It also looks like the arduino is sending data very rapidly." Are you referring to date rate or frequency of sends? And is it more reliable to use a lower date rate and smaller payload size?

from rf24network.

spaniakos avatar spaniakos commented on August 26, 2024

I am referring to frequency of sends.
If you have many, then the fifo wont store them all.

On top of that . If you have linear code ( straigt execution line ) the. As
you increase the commands , you might need ti decrease the frequency of
senda , especially when using cryptographic libraries, we are talking about
milliseconds here.
On Dec 4, 2014 11:19 AM, "Onmt39" [email protected] wrote:

Thank you, the RPi doesn't acknowledge any received payloads when
radio.stopListening() or radio.powerDown() is used. I'll use that before
exiting.

Earlier you said " It also looks like the arduino is sending data very
rapidly." Are you referring to date rate or frequency of sends? And is it
more reliable to use a lower date rate and smaller payload size?


Reply to this email directly or view it on GitHub
#29 (comment).

from rf24network.

Onmt39 avatar Onmt39 commented on August 26, 2024

The sends will not be so frequent as its monitoring doors and turning
lights on instead of push buttons.

Will a lower date rate eg. 250kbps significantly slow down a linear code
(waiting for other node to acknowledge) Ie.
milliseconds?

On Thursday, December 4, 2014, Georgios Spanos [email protected]
wrote:

I am referring to frequency of sends.
If you have many, then the fifo wont store them all.

On top of that . If you have linear code ( straigt execution line ) the.
As
you increase the commands , you might need ti decrease the frequency of
senda , especially when using cryptographic libraries, we are talking
about
milliseconds here.
On Dec 4, 2014 11:19 AM, "Onmt39" <[email protected]
javascript:_e(%7B%7D,'cvml','[email protected]');> wrote:

Thank you, the RPi doesn't acknowledge any received payloads when
radio.stopListening() or radio.powerDown() is used. I'll use that before
exiting.

Earlier you said " It also looks like the arduino is sending data very
rapidly." Are you referring to date rate or frequency of sends? And is
it
more reliable to use a lower date rate and smaller payload size?


Reply to this email directly or view it on GitHub
#29 (comment).


Reply to this email directly or view it on GitHub
#29 (comment).

from rf24network.

TMRh20 avatar TMRh20 commented on August 26, 2024

I was also referring to frequency of sends.
There doesn't seem to be a real one-size-fits-all solution to reliability vs data rates etc. because it typically depends on the environment and setup of the network. Slower data rates provide longer range and potentially higher reliability in some cases, but with many nodes in a small area, higher data rates provide higher throughput, thus less interference with other nodes.

Using slower data rates will noticeably affect response times, since transmissions at 250Kbps will take four times as long as with 1Mbps. I haven't done much specific testing regarding payload size vs reliability, but the network DEV library uses dynamic paylods, so smaller payloads should go through faster. The RF24Network library also has its own buffers, so will store up to 5 additional payloads in addition to the 3 stored by the radio modules (this code in dev needs cleanup).

from rf24network.

spaniakos avatar spaniakos commented on August 26, 2024

This discussion gives me ideas about parallel programming. I will check the
compatibility with raspberry pi and galileo with fork and mutex and
hopefully i can achieve 24/7 radio send receive, and all the other code can
run independently. Ofc that can happen with back end nodejs or python, but
with this the possibilities will be endless :-)
On Dec 4, 2014 9:38 PM, "TMRh20" [email protected] wrote:

I was also referring to frequency of sends.
There doesn't seem to be a real one-size-fits-all solution to reliability
vs data rates etc. because it typically depends on the environment and
setup of the network. Slower data rates provide longer range and
potentially higher reliability in some cases, but with many nodes in a
small area, higher data rates provide higher throughput, thus less
interference with other nodes.

Using slower data rates will noticeably affect response times, since
transmissions at 250Kbps will take four times as long as with 1Mbps. I
haven't done much specific testing regarding payload size vs reliability,
but the network DEV library uses dynamic paylods, so smaller payloads
should go through faster. The RF24Network library also has its own buffers,
so will store up to 5 additional payloads in addition to the 3 stored by
the radio modules (this code in dev needs cleanup).


Reply to this email directly or view it on GitHub
#29 (comment).

from rf24network.

Onmt39 avatar Onmt39 commented on August 26, 2024

The dev RF24Network library is it working? I am only transmitting one byte and the dynamic payload sounds good including the additional buffer.

from rf24network.

TMRh20 avatar TMRh20 commented on August 26, 2024

"The dev RF24Network library is it working? "
This seems to me a really odd question. Its development... if you have to ask, you probably shouldn't be using the dev lib.

from rf24network.

Onmt39 avatar Onmt39 commented on August 26, 2024

Ok fair enough,
Thanks for clearing up my problem

from rf24network.

Related Issues (20)

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.