Coder Social home page Coder Social logo

sparkfun / qwiic_openlog Goto Github PK

View Code? Open in Web Editor NEW
21.0 5.0 6.0 7.51 MB

Open source I2C based datalogger. The bigger, better cousin to the original serial OpenLog.

License: Other

C++ 100.00%
sparkfun sparkfun-products datalogger logger arduino

qwiic_openlog's Introduction

SparkFun Qwiic OpenLog

SparkFun Qwiic OpenLog

SparkFun Qwiic OpenLog (DEV-15164)

The Qwiic system makes it easy to read all sorts of sensors, but what if you want to log that data? Qwiic OpenLog is an easy to use I2C based data logger. Simply write code like:

recordToOpenLog("The battery voltage is:");
recordToOpenLog(batteryVoltage);

And your data will be recorded to LOG00001.TXT for later review.

The SparkFun Qwiic OpenLog is the smarter and better looking cousin to the extremely popular OpenLog. We've ported the serial based interface to I2C. Now you can daisy chain lots of I2C devices and log them all without taking up your serial port.

We've written a large number of example sketches to show how to record logs, create new logs, create and navigate directories, remove files and directories, and read the contents of files.

Qwiic OpenLog supports clock stretching which means it performs even better than the original! Qwiic OpenLog will record data up to 21,000 bytes per second at 400kHz. As the receive buffer fills up QOL will hold the clock line letting the master know that it is busy. Once QOL is finished with a task it releases the clock allowing the data to continue flowing without corruption.

Need to get freaky and have multiple data loggers on the same bus? You're in luck. Qwiic OpenLog has both a solder jumper to allow for two devices on the same bus as well as a software setting to allow for the setting of any I2C address. Don't get too freaky though; the limit is 111 devices (0x08 to 0x77) on the same bus. Any microSD card will work so with 64GB cards you'll be limited to approximately 7 Terabytes of storage :(

We will be adding more features to the firmware over time and we've made it very easy to upgrade! If you're comfortable sending a sketch to an Uno then you can upgrade the firmware on Qwiic OpenLog.

Repository Contents

  • /Firmware/Qwiic_OpenLog - The core sketch that runs Qwiic OpenLog
  • /Hardware - Eagle design files (.brd, .sch)

Documentation

License Information

This product is open source!

Please review the LICENSE.md file for license information.

If you have any questions or concerns on licensing, please contact [email protected].

Please use, reuse, and modify these files as you see fit. Please maintain attribution to SparkFun Electronics and release any derivative under the same license.

Distributed as-is; no warranty is given.

  • Your friends at SparkFun.

qwiic_openlog's People

Contributors

andyengland521 avatar loricrotser avatar nseidle avatar s-m-t avatar santaimpersonator avatar

Stargazers

 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

qwiic_openlog's Issues

Errors in code

case ERROR_VOLUME_INIT:
NewSerial.print(F("volume.init"));
blink_error(ERROR_SD_INIT);
break;

this line should not be

  case ERROR_VOLUME_INIT:
      NewSerial.print(F("volume.init"));
      blink_error(ERROR_VOLUME_INIT);
      break;

otherwise, all errors blink the same number of times, a little bit confusing

Add Pullup on CS

Add ~10k pull up on SD CS so that the device can be programmed in test jig with SD card inserted. Otherwise the CS pin is left floating and can cause errors when the SD card tries to take over MISO during programming and testing.

Example sketch won't compile, "default argument given for parameter 2"

Example 1 sketch won't compile, I get the following error message(s):

Arduino: 1.8.8 (Windows 10), Board: "SparkFun SAMD21 Pro RF"

C:\Users\Mike\Documents\Arduino\libraries\SparkFun_Qwiic_OpenLog\src\SparkFun_Qwiic_OpenLog_Arduino_Library.cpp:274:73: error: default argument given for parameter 2 of 'boolean OpenLog::sendCommand(uint8_t, String) [-fpermissive]

boolean OpenLog::sendCommand(uint8_t registerNumber, String option1 = "")

In file included from C:\Users\Mike\Documents\Arduino\libraries\SparkFun_Qwiic_OpenLog\src\SparkFun_Qwiic_OpenLog_Arduino_Library.cpp:28:0:

C:\Users\Mike\Documents\Arduino\libraries\SparkFun_Qwiic_OpenLog\src\SparkFun_Qwiic_OpenLog_Arduino_Library.h:148:13: error: after previous specification in 'boolean OpenLog::sendCommand(uint8_t, String)' [-fpermissive]

boolean sendCommand(uint8_t registerNumber, String option1 = "");

exit status 1
Error compiling for board SparkFun SAMD21 Pro RF.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

If I remove the default argument from the sendCommand definition in the .cpp file, it compiles, i.e. when:
boolean OpenLog::sendCommand(uint8_t registerNumber, String option1)
replaces:
boolean OpenLog::sendCommand(uint8_t registerNumber, String option1 = "")

Using a SparkFun SAMD21 Pro RF and the SparkX qwiic OpenLog, I have another issue once the code is uploaded - the output of my .txt file on the SD card, running Example 1, looks like:
txt_file_output

This matches an issue I had with another version of the library (as of Jan 26th, 2019) when used with the same hardware - randomly missing characters in the output file, skipped new lines, although no random up arrows (raised as an issue in the github for that version of the library, here). Running the same sketch multiple times resulted in completely random point of error, i.e. sometimes a new line would come out correctly, other times it wouldn't, and would cut off in random spots. Now, with this version, I get the random up-arrows, as well as the randomly cut off lines.

Last I checked, the circa 1/26/2019 version of the library worked fine when the SparkX qwiic OpenLog was hooked up to a BlackBoard instead of the SAMD21 Pro RF.

Compilation errors

Compile firmware code returning errors

Processing Qwiic_OpenLog (src_filter: +<Qwiic_OpenLog.cpp>; platform: atmelavr; framework: arduino; board: ATmega328; targets: program; monitor_speed: 115200; lib_deps: SdFat=https://github.com/greiman/SdFat-beta.git#7016042d22ec9e4a3fe93565bfff1d61fb8271e2)
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
CONFIGURATION: https://docs.platformio.org/page/boards/atmelavr/ATmega328.html
PLATFORM: Atmel AVR 2.0.0 > ATmega328
HARDWARE: ATMEGA328 16MHz, 2KB RAM, 31.50KB Flash
PACKAGES: toolchain-atmelavr 1.50400.190710 (5.4.0), framework-arduino-avr-minicore 2.0.3, tool-avrdude 1.60300.190628 (6.3.0)
LDF: Library Dependency Finder -> http://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 9 compatible libraries
Scanning dependencies...
Dependency Graph
|-- <SdFat> #7016042 [git+https://github.com/greiman/SdFat-beta.git#7016042d22ec9e4a3fe93565bfff1d61fb8271e2] (/Users/prakash/Projects/embedded/Qwiic_OpenLog/.pio/libdeps/Qwiic_OpenLog/SdFat)
|   |-- <SPI> 1.0 (/Users/prakash/.platformio/packages/framework-arduino-avr-minicore/libraries/SPI)
|-- <EEPROM> 2.0 (/Users/prakash/.platformio/packages/framework-arduino-avr-minicore/libraries/EEPROM)
|-- <SPI> 1.0 (/Users/prakash/.platformio/packages/framework-arduino-avr-minicore/libraries/SPI)
|-- <Wire> 1.0 (/Users/prakash/.platformio/packages/framework-arduino-avr-minicore/libraries/Wire)
Building in release mode
avr-g++ -o .pio/build/Qwiic_OpenLog/src/Qwiic_OpenLog.cpp.o -c -fno-exceptions -fno-threadsafe-statics -fpermissive -std=gnu++11 -Os -Wall -ffunction-sections -fdata-sections -flto -mmcu=atmega328 -DPLATFORMIO=40100 -DARDUINO_AVR_ATmega328 -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -Iinclude -Isrc -I/Users/prakash/.platformio/packages/framework-arduino-avr-minicore/libraries/Wire/src -I/Users/prakash/.platformio/packages/framework-arduino-avr-minicore/libraries/EEPROM/src -I.pio/libdeps/Qwiic_OpenLog/SdFat -I/Users/prakash/.platformio/packages/framework-arduino-avr-minicore/libraries/SPI/src -I/Users/prakash/.platformio/packages/framework-arduino-avr-minicore/cores/MiniCore -I/Users/prakash/.platformio/packages/framework-arduino-avr-minicore/variants/standard src/Qwiic_OpenLog.cpp
In file included from .pio/libdeps/Qwiic_OpenLog/SdFat/SdFat/src/FatLib/FatLib.h:28:0,
                 from .pio/libdeps/Qwiic_OpenLog/SdFat/SdFat/src/SdFat.h:27,
                 from src/Qwiic_OpenLog.cpp:93:
.pio/libdeps/Qwiic_OpenLog/SdFat/SdFat/src/FatLib/StdioStream.h:289:24: warning: 'prog_char' is deprecated [-Wdeprecated-declarations]
   int fputs_P(PGM_P str);
                        ^
In file included from src/Qwiic_OpenLog.cpp:94:0:
include/SerialPort.h:243:41: warning: 'prog_char' is deprecated [-Wdeprecated-declarations]
   buf_size_t put_P(PGM_P b, buf_size_t n);
                                         ^
include/SerialPort.h:547:35: warning: 'prog_char' is deprecated [-Wdeprecated-declarations]
   size_t write_P(PGM_P b, size_t n) {
                                   ^
include/SerialPort.h: In member function 'size_t SerialPort<PortNumber, RxBufSize, TxBufSize>::write(const __FlashStringHelper*)':
include/SerialPort.h:583:22: warning: 'prog_char' is deprecated: prog_char type is deprecated. [-Wdeprecated-declarations]
     const prog_char* p = (const prog_char*)s;
                      ^
In file included from /Users/prakash/.platformio/packages/framework-arduino-avr-minicore/cores/MiniCore/Arduino.h:28:0,
                 from /Users/prakash/.platformio/packages/framework-arduino-avr-minicore/libraries/Wire/src/Wire.h:25,
                 from src/Qwiic_OpenLog.cpp:91:
/Users/prakash/.platformio/packages/toolchain-atmelavr/avr/include/avr/pgmspace.h:354:14: note: declared here
 typedef char prog_char __attribute__((__progmem__,deprecated("prog_char type is deprecated.")));
              ^
In file included from src/Qwiic_OpenLog.cpp:94:0:
include/SerialPort.h:583:42: warning: 'prog_char' is deprecated: prog_char type is deprecated. [-Wdeprecated-declarations]
     const prog_char* p = (const prog_char*)s;
                                          ^
In file included from /Users/prakash/.platformio/packages/framework-arduino-avr-minicore/cores/MiniCore/Arduino.h:28:0,
                 from /Users/prakash/.platformio/packages/framework-arduino-avr-minicore/libraries/Wire/src/Wire.h:25,
                 from src/Qwiic_OpenLog.cpp:91:
/Users/prakash/.platformio/packages/toolchain-atmelavr/avr/include/avr/pgmspace.h:354:14: note: declared here
 typedef char prog_char __attribute__((__progmem__,deprecated("prog_char type is deprecated.")));
              ^
src/Qwiic_OpenLog.cpp: In function 'void recordConfigFile()':
src/Qwiic_OpenLog.cpp:603:62: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   if (myFile.write(settings_string, strlen(settings_string)) != strlen(settings_string))
                                                              ^
src/Qwiic_OpenLog.cpp: In function 'void loadArrayWithFileName(FatFile*, char*)':
src/Qwiic_OpenLog.cpp:1183:53: warning: invalid conversion from 'byte* {aka unsigned char*}' to 'char*' [-fpermissive]
   responseSize = sprintf(responseBuffer, "%s", fname) + 1; //Add 1 for null terminator
                                                     ^
In file included from /Users/prakash/.platformio/packages/framework-arduino-avr-minicore/cores/MiniCore/Print.h:24:0,
                 from /Users/prakash/.platformio/packages/framework-arduino-avr-minicore/cores/MiniCore/Stream.h:26,
                 from /Users/prakash/.platformio/packages/framework-arduino-avr-minicore/cores/MiniCore/HardwareSerial.h:29,
                 from /Users/prakash/.platformio/packages/framework-arduino-avr-minicore/cores/MiniCore/Arduino.h:288,
                 from /Users/prakash/.platformio/packages/framework-arduino-avr-minicore/libraries/Wire/src/Wire.h:25,
                 from src/Qwiic_OpenLog.cpp:91:
/Users/prakash/.platformio/packages/toolchain-atmelavr/avr/include/stdio.h:671:12: note:   initializing argument 1 of 'int sprintf(char*, const char*, ...)'
 extern int sprintf(char *__s, const char *__fmt, ...);
            ^
src/Qwiic_OpenLog.cpp: In function 'void listFiles(char*)':
src/Qwiic_OpenLog.cpp:1206:12: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
     myData = "*\0";       // use global wildcard=
            ^
src/Qwiic_OpenLog.cpp: In function 'void receiveEvent(int)':
src/Qwiic_OpenLog.cpp:1363:31: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int regNum = 0; regNum < (sizeof(memoryMap) / sizeof(byte)); regNum++)
                               ^
src/Qwiic_OpenLog.cpp:1369:52: warning: invalid conversion from 'byte* {aka unsigned char*}' to 'char*' [-fpermissive]
       functions[regNum].handleFunction(incomingData);
                                                    ^
In file included from src/Qwiic_OpenLog.cpp:96:0:
src/Qwiic_OpenLog.cpp: At top level:
.pio/libdeps/Qwiic_OpenLog/SdFat/SdFat/src/FreeStack.h:40:12: warning: 'FreeStack' defined but not used [-Wunused-function]
 static int FreeStack() {
            ^
avr-g++ -o .pio/build/Qwiic_OpenLog/firmware.elf -Os -mmcu=atmega328 -Wl,--gc-sections -flto -fuse-linker-plugin .pio/build/Qwiic_OpenLog/src/Qwiic_OpenLog.cpp.o -L.pio/build/Qwiic_OpenLog -Wl,--start-group .pio/build/Qwiic_OpenLog/lib10a/libSPI.a .pio/build/Qwiic_OpenLog/lib201/libSdFat.a .pio/build/Qwiic_OpenLog/lib356/libEEPROM.a .pio/build/Qwiic_OpenLog/libff3/libWire.a .pio/build/Qwiic_OpenLog/libFrameworkArduinoVariant.a .pio/build/Qwiic_OpenLog/libFrameworkArduino.a -lm -Wl,--end-group
/var/folders/f2/ps6dm9rs3y7dqg7xr8_k9_2h0000gn/T//ccy0Fwvq.ltrans0.ltrans.o: In function `SerialPort<(unsigned char)0, 32u, 32u>::flush()':
<artificial>:(.text+0x6c6): undefined reference to `txRingBuf'
<artificial>:(.text+0x6ca): undefined reference to `txRingBuf'
<artificial>:(.text+0x6ce): undefined reference to `txRingBuf'
<artificial>:(.text+0x6d2): undefined reference to `txRingBuf'
/var/folders/f2/ps6dm9rs3y7dqg7xr8_k9_2h0000gn/T//ccy0Fwvq.ltrans0.ltrans.o: In function `SerialPort<(unsigned char)0, 32u, 32u>::peek()':
<artificial>:(.text+0xe1c): undefined reference to `rxRingBuf'
<artificial>:(.text+0xe1e): undefined reference to `rxRingBuf'
<artificial>:(.text+0xe20): undefined reference to `SerialRingBuffer::peek()'
/var/folders/f2/ps6dm9rs3y7dqg7xr8_k9_2h0000gn/T//ccy0Fwvq.ltrans0.ltrans.o: In function `SerialPort<(unsigned char)0, 32u, 32u>::read()':
<artificial>:(.text+0xe34): undefined reference to `rxRingBuf'
<artificial>:(.text+0xe36): undefined reference to `rxRingBuf'
<artificial>:(.text+0xe38): undefined reference to `SerialRingBuffer::get(unsigned char*)'
/var/folders/f2/ps6dm9rs3y7dqg7xr8_k9_2h0000gn/T//ccy0Fwvq.ltrans0.ltrans.o: In function `SerialPort<(unsigned char)0, 32u, 32u>::available()':
<artificial>:(.text+0xe52): undefined reference to `rxRingBuf'
<artificial>:(.text+0xe54): undefined reference to `rxRingBuf'
<artificial>:(.text+0xe56): undefined reference to `SerialRingBuffer::available()'
/var/folders/f2/ps6dm9rs3y7dqg7xr8_k9_2h0000gn/T//ccy0Fwvq.ltrans0.ltrans.o: In function `SerialPort<(unsigned char)0, 32u, 32u>::write(unsigned char const*, unsigned int)':
<artificial>:(.text+0xe76): undefined reference to `txRingBuf'
<artificial>:(.text+0xe78): undefined reference to `txRingBuf'
<artificial>:(.text+0xe7a): undefined reference to `SerialRingBuffer::put(unsigned char const*, unsigned int)'
/var/folders/f2/ps6dm9rs3y7dqg7xr8_k9_2h0000gn/T//ccy0Fwvq.ltrans0.ltrans.o: In function `SerialPort<(unsigned char)0, 32u, 32u>::write(unsigned char)':
<artificial>:(.text+0xeaa): undefined reference to `txRingBuf'
<artificial>:(.text+0xeac): undefined reference to `txRingBuf'
<artificial>:(.text+0xeae): undefined reference to `SerialRingBuffer::put(unsigned char)'
/var/folders/f2/ps6dm9rs3y7dqg7xr8_k9_2h0000gn/T//ccy0Fwvq.ltrans0.ltrans.o: In function `global constructors keyed to 65535_0_Qwiic_OpenLog.cpp.o.3638':
<artificial>:(.text.startup+0x40): undefined reference to `rxRingBuf'
<artificial>:(.text.startup+0x42): undefined reference to `rxRingBuf'
<artificial>:(.text.startup+0x44): undefined reference to `SerialRingBuffer::init(unsigned char*, unsigned int)'
<artificial>:(.text.startup+0x50): undefined reference to `txRingBuf'
<artificial>:(.text.startup+0x52): undefined reference to `txRingBuf'
<artificial>:(.text.startup+0x54): undefined reference to `SerialRingBuffer::init(unsigned char*, unsigned int)'
/var/folders/f2/ps6dm9rs3y7dqg7xr8_k9_2h0000gn/T//ccy0Fwvq.ltrans0.ltrans.o: In function `main':
<artificial>:(.text.startup+0xea): undefined reference to `fopen'
<artificial>:(.text.startup+0x170): undefined reference to `fopen'
collect2: error: ld returned 1 exit status

Characters dropped on Teensy 4.0

When I compile and run the code below for a Teensy 4.0, many characters are dropped. A typical output is also shown below. The errors seem to be random. Adding delay(20) lines in the code seems to have no effect. When I run the same code on an Arduino Mini Pro, the output is perfect. I really, really would like to get this fixed. Any ideas?

Just as a side note, I should mention that there is a compile error when compiling for a Teensy 3.2. I don't need this but I thought someone should know.


#include <Wire.h>
#include "SparkFun_Qwiic_OpenLog_Arduino_Library.h"
OpenLog myLog; //Create instance

int ledPin = 13; //Status LED connected to digital pin 13
char message[100] = "";

void setup() {
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);
  Wire.begin(); //Initialize I2C
  myLog.begin(); //Open connection to OpenLog (no pun intended)
  for (float i = 0.0; i < 9.1; i += 0.5) {
    Serial.print(i); Serial.print(",");
    myLog.print(i); myLog.print(",");
    Serial.print(sqrt(i)); Serial.print(",");
    myLog.print(sqrt(i)); myLog.print(",");
    Serial.print(i / 0.99); Serial.print(","); 
    myLog.print(i / 0.99); myLog.print(","); 
    Serial.print(i * 1.1), Serial.print(",");
    myLog.print(i * 1.1), myLog.print(",");
    Serial.println(i);
    myLog.println(i);
  }
  myLog.syncFile();
}

void loop() {
  digitalWrite(ledPin, HIGH);
  delay(100);
  digitalWrite(ledPin, LOW);
  delay(1000);
}

0.00,0.00,0.00,0.00,0.00
0.50,0.710.51,0.55,0.50
1.00,1.00,1.01,1.10,1.00
1.50,1.22,1.52,1.65,1.50
2.00,1.41,2.02,2.20,2.00
2.50,1.58,2.53,2.75,2.50
3.00,1.73,3.03,3.30,3.00
3.50,1.87,3.5,3.85,3.50
4.00,2.00,4.04,4.40,4.00
4.50,2.12,4.55,4.95,4.50
5.00,2.24,5.05,5.50,5.00
5.0,2.35,5.56,6.05,5.50
6.00,2.45,6.06,6.60,6.00
6.50,2.55,6.57,7.15,6.50
7.00,2.65,7.07,7.0,7.00
7.50,2.74,7.58,8.25,7.50
8.00,2.83,8.08,8.80,8.00
8.50,2.92,8.59,9.35,8.50
9.00,3.00,9.09,9.90,9.0

Can't flash OpenLog Qwiic

Hi!

My goal is to use OpenLog Qwiic as a standalone logger for the SparkFun GPS-RTK2 Board - ZED-F9P (Qwiic).

I've quick tested the OpenLog with an Arduino Uno and the OpenLog arduino library, and it's working.
My first step is simply updating the firmware with the latest one available here.
Then I will customize the code to log the F9P (any help is welcome).

But, I can't flash the OpenLog.

I've soldered the ftdi pins
Connected the OpenLog with an Adafruit Ftdi Friend/Sparkfun FTDI Basic 3.3v to a Windows Computer/Ubuntu Computer, and I always have the same problem :

avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0xde

I don't understand where is the problem.

Problem on interfacing Qwiic OpenLog throught NUCLEO STM32 L432KC

I'm trying to write my own library for my own use, based on Arduino library and information that SparkFun provided about this logger but i'm always recievieng HAL_error. I do not know where to find help or information about configuring this device, and it feels like register map is useless because any of those addresses doesn't respond.

How to set the "start position of each new read"?

In register 0x0A I should write a string of characters to change the start position of each new read.

newthing

It works, when I write 1 Byte after the command 0x0A. I can change the start position from 0 to 255. But files are bigger.

How to format the "string" with the offset value?

And where comes the "Start Position" command? Before or after the "Read File" command. I have testet both.

OpenLog Qwiic not working with STM32F429 Nucleo 144 Board

I am trying to log the data from STM32F429 board to Qwiic logger through I2C port. Below is settings for I2C in STM32F429
Address Mode: 10Bit
Clock Speed: 400K

Following commands are sent from STM32F429 board

  1. Sent Data as "Testing"
  2. Sent Register Address "13"
  3. Sent Register Address "10"
  4. Sent Register Address "17"

The I2C device ID used to communicate with Qwiic log is 42.

Please help me to solve the above issue. I have tested the Qwiic board with Arduino UNO and it is working.

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.