Git Product home page Git Product logo

lua-periphery's Introduction

lua-periphery Build Status GitHub release License

Linux Peripheral I/O (GPIO, LED, PWM, SPI, I2C, MMIO, Serial) with Lua

lua-periphery is a library for GPIO, LED, PWM, SPI, I2C, MMIO, and Serial peripheral I/O interface access in userspace Linux. It is useful in embedded Linux environments (including Raspberry Pi, BeagleBone, etc. platforms) for interfacing with external peripherals. lua-periphery is compatible with Lua 5.1 (including LuaJIT), Lua 5.2, Lua 5.3, and Lua 5.4, has no dependencies outside the standard C library and Linux, is portable across architectures, and is MIT licensed.

Using Python or C? Check out the python-periphery and c-periphery projects.

Contributed libraries: java-periphery, dart_periphery

Examples

GPIO

local GPIO = require('periphery').GPIO

-- Open GPIO /dev/gpiochip0 line 10 with input direction
local gpio_in = GPIO("/dev/gpiochip0", 10, "in")
-- Open GPIO /dev/gpiochip0 line 12 with output direction
local gpio_out = GPIO("/dev/gpiochip0", 12, "out")

local value = gpio_in:read()
gpio_out:write(not value)

gpio_in:close()
gpio_out:close()

Go to GPIO documentation.

LED

local LED = require('periphery').LED

-- Open LED led0
local led = LED("led0")

-- Turn on LED (set max brightness)
led:write(true)

-- Set half brightness
led:write(math.floor(led.max_brightness / 2))

-- Turn off LED (set zero brightness)
led:write(false)

led:close()

Go to LED documentation.

PWM

local PWM = require('periphery').PWM

-- Open PWM chip 0, channel 10
local pwm = PWM(0, 10)

-- Set frequency to 1 kHz
pwm.frequency = 1e3
-- Set duty cycle to 75%
pwm.duty_cycle = 0.75

-- Enable PWM output
pwm:enable()

pwm:close()

Go to PWM documentation.

SPI

local SPI = require('periphery').SPI

-- Open spidev1.0 with mode 0 and max speed 1MHz
local spi = SPI("/dev/spidev1.0", 0, 1e6)

local data_out = {0xaa, 0xbb, 0xcc, 0xdd}
local data_in = spi:transfer(data_out)

print(string.format("shifted out {0x%02x, 0x%02x, 0x%02x, 0x%02x}", unpack(data_out)))
print(string.format("shifted in  {0x%02x, 0x%02x, 0x%02x, 0x%02x}", unpack(data_in)))

spi:close()

Go to SPI documentation.

I2C

local I2C = require('periphery').I2C

-- Open i2c-0 controller
local i2c = I2C("/dev/i2c-0")

-- Read byte at address 0x100 of EEPROM at 0x50
local msgs = { {0x01, 0x00}, {0x00, flags = I2C.I2C_M_RD} }
i2c:transfer(0x50, msgs)
print(string.format("0x100: 0x%02x", msgs[2][1]))

i2c:close()

Go to I2C documentation.

MMIO

local MMIO = require('periphery').MMIO

-- Open am335x real-time clock subsystem page
local rtc_mmio = MMIO(0x44E3E000, 0x1000)

-- Read current time
local rtc_secs = rtc_mmio:read32(0x00)
local rtc_mins = rtc_mmio:read32(0x04)
local rtc_hrs = rtc_mmio:read32(0x08)

print(string.format("hours: %02x minutes: %02x seconds: %02x", rtc_hrs, rtc_mins, rtc_secs))

rtc_mmio:close()

-- Open am335x control module page
local ctrl_mmio = MMIO(0x44E10000, 0x1000)

-- Read MAC address
local mac_id0_lo = ctrl_mmio:read32(0x630)
local mac_id0_hi = ctrl_mmio:read32(0x634)

print(string.format("MAC address: %04x%08x", mac_id0_lo, mac_id0_hi))

ctrl_mmio:close()

Go to MMIO documentation.

Serial

local Serial = require('periphery').Serial

-- Open /dev/ttyUSB0 with baudrate 115200, and defaults of 8N1, no flow control
local serial = Serial("/dev/ttyUSB0", 115200)

serial:write("Hello World!")

-- Read up to 128 bytes with 500ms timeout
local buf = serial:read(128, 500)
print(string.format("read %d bytes: _%s_", #buf, buf))

serial:close()

Go to Serial documentation.

Error Handling

lua-periphery errors are descriptive table objects with an error code string, C errno, and a user message.

-- Example of error caught with pcall()
> status, err = pcall(function () spi = periphery.SPI("/dev/spidev1.0", 0, 1e6) end)
> =status
false
> dump(err)
{
  message = "Opening SPI device \"/dev/spidev1.0\": Permission denied [errno 13]",
  c_errno = 13,
  code = "SPI_ERROR_OPEN"
}
> 

-- Example of error propagated to user
> periphery = require('periphery')
> spi = periphery.SPI('/dev/spidev1.0', 0, 1e6)
Opening SPI device "/dev/spidev1.0": Permission denied [errno 13]
> 

Note about Lua 5.1

Lua 5.1 does not automatically render the string representation of error objects that are reported to the console, and instead shows the following error message:

> periphery = require('periphery')
> gpio = periphery.GPIO(14, 'in')
(error object is not a string)
> 

These errors can be caught with pcall() and rendered in their string representation with tostring(), print(), or by evaluation in the interactive console:

> periphery = require('periphery')
> gpio, err = pcall(periphery.GPIO, 14, 'in')
> =tostring(err)
Opening GPIO: opening 'export': Permission denied [errno 13]
> print(err)
Opening GPIO: opening 'export': Permission denied [errno 13]
> =err
Opening GPIO: opening 'export': Permission denied [errno 13]
> 

This only applies to Lua 5.1. LuaJIT and Lua 5.2 onwards automatically render the string representation of error objects that are reported to the console.

Documentation

man page style documentation for each interface is available in docs folder.

Installation

Build and install with LuaRocks

$ sudo luarocks install lua-periphery

Build and install from source

Clone lua-periphery recursively to also fetch c-periphery, which lua-periphery is built on.

$ git clone --recursive https://github.com/vsergeev/lua-periphery.git
$ cd lua-periphery
$ make clean all
$ cp periphery.so /path/to/lua/libs/

Place periphery.so in a directory searched by the Lua package.cpath variable. For example: /usr/lib/lua/5.3/, the same directory as other Lua sources, etc.

lua-periphery can then be loaded in lua with periphery = require('periphery').

Cross-compiling from Source

Set the CROSS_COMPILE environment variable with the cross-compiler prefix when calling make. Your target's sysroot must provide the Lua includes.

$ CROSS=arm-linux- make clean all
cd c-periphery && make clean
make[1]: Entering directory '/home/anteater/projects/software/lua-periphery/c-periphery'
rm -rf periphery.a obj tests/test_serial tests/test_i2c tests/test_gpio_sysfs tests/test_mmio tests/test_spi tests/test_gpio
make[1]: Leaving directory '/home/anteater/projects/software/lua-periphery/c-periphery'
rm -rf periphery.so
cd c-periphery; make
make[1]: Entering directory '/home/anteater/projects/software/lua-periphery/c-periphery'
mkdir obj
arm-linux-gcc -std=gnu99 -pedantic -Wall -Wextra -Wno-unused-parameter  -fPIC -DPERIPHERY_VERSION_COMMIT=\"v2.0.1\"  -c src/gpio.c -o obj/gpio.o
arm-linux-gcc -std=gnu99 -pedantic -Wall -Wextra -Wno-unused-parameter  -fPIC -DPERIPHERY_VERSION_COMMIT=\"v2.0.1\"  -c src/spi.c -o obj/spi.o
arm-linux-gcc -std=gnu99 -pedantic -Wall -Wextra -Wno-unused-parameter  -fPIC -DPERIPHERY_VERSION_COMMIT=\"v2.0.1\"  -c src/i2c.c -o obj/i2c.o
arm-linux-gcc -std=gnu99 -pedantic -Wall -Wextra -Wno-unused-parameter  -fPIC -DPERIPHERY_VERSION_COMMIT=\"v2.0.1\"  -c src/mmio.c -o obj/mmio.o
arm-linux-gcc -std=gnu99 -pedantic -Wall -Wextra -Wno-unused-parameter  -fPIC -DPERIPHERY_VERSION_COMMIT=\"v2.0.1\"  -c src/serial.c -o obj/serial.o
arm-linux-gcc -std=gnu99 -pedantic -Wall -Wextra -Wno-unused-parameter  -fPIC -DPERIPHERY_VERSION_COMMIT=\"v2.0.1\"  -c src/version.c -o obj/version.o
arm-linux-ar rcs periphery.a obj/gpio.o obj/spi.o obj/i2c.o obj/mmio.o obj/serial.o obj/version.o
make[1]: Leaving directory '/home/anteater/projects/software/lua-periphery/c-periphery'
arm-linux-gcc  -std=c99 -pedantic -D_XOPEN_SOURCE=700 -Wall -Wextra -Wno-unused-parameter  -fPIC -I.  -Iinc  -shared src/lua_periphery.c src/lua_mmio.c src/lua_
gpio.c src/lua_spi.c src/lua_i2c.c src/lua_serial.c c-periphery/periphery.a -o periphery.so
$ file periphery.so
periphery.so: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, not stripped
$

Testing

The tests located in the tests folder may be run under Lua to test the correctness and functionality of lua-periphery. Some tests require interactive probing (e.g. with an oscilloscope), the installation of a physical loopback, or the existence of a particular device on a bus. See the usage of each test for more details on the required setup.

License

lua-periphery is MIT licensed. See the included LICENSE file.

lua-periphery's People

Contributors

gw0 avatar ikarius avatar niziak avatar vsergeev 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

lua-periphery's Issues

Version 1.0.3 on raspbian - compile error

Current github version does not compile on raspbian / Lua 5.1
First you have to set include-path before make: export LUA_INCDIR=/usr/include/lua5.1
Then when compiling:

src/lua_i2c.c: In function ‘luaopen_periphery_i2c’:
src/lua_i2c.c:371:5: error: ‘I2C_M_STOP’ undeclared (first use in this function)
src/lua_i2c.c:371:5: note: each undeclared identifier is reported only once for each function it appears in
Makefile:40: recipe for target 'periphery.so' failed

GPIO initialization overwrites current value

I'm using GPIO periphery with a nginx web server (to power on/off some electrical devices).
I want to read and display the current status (on/off) on the web page.
But each time I open a gpio pin to read the current value the value is set to 0 (false) on initialization.

local gpio = require('periphery').GPIO
-- The next line resets the value of pin 12 to false (even if it was previously set to true)
local gpio_out = gpio(12, "out")
local value = gpio_out:read()
print(value)
gpio_out:write(not value)
gpio_out:close()
os.exit()

If you call the program twice (or multiple times) you will see that the value of pin 12 is always false.
Is it possible to open a pin without initializing/overwriting a previously set value?

i2c:transfer exception

hi its really a wonderful tool but I meet the following error when running i2c test:

local I2C = require('periphery').I2C
-- Open i2c-0 controller
local i2c = I2C("/dev/i2c-0")

-- Read byte at address 0x100 of EEPROM at 0x50
-- local msgs = { {0xac,0x33,0x00}, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,flags = I2C.I2C_M_RD} }
 local msgs = { {0x01, 0x00}, {0x00, flags = I2C.I2C_M_RD} }
i2c:transfer(0x38, msgs)
print(string.format("0x100: 0x%02x", msgs[2][1]))
i2c:close()

when run ,it returns

$ lua ./api_iic.lua
lua: Error: I2C transfer: Invalid argument [errno 22]

my version is

$ lua -v
Lua 5.3.3  Copyright (C) 1994-2016 Lua.org, PUC-Rio

it will be great thansk if you would help to provide more guide to location the problem thanks~

local GPIO = require('periphery').GPIO returns nil

While working with lua 5.2 and a local build of lua-periphery the require is returning nil.
If I have LUA_CPATH setup wrong, I get complaints about not finding the library.

So it's as though the .so is being found, but for some reason it's not initialized properly.

Thanks for any pointers, I'm very excited to use this library.

Support for internal pull down resistors

The Raspberry Pi has internal Pull Down resistors that can optionally be enabled (This article demonstrates how to do that in Python).

I have not found any option to do this with lua-periphery... Is this an oversight in the library or am I missing something? Should it be implemented? Or is it just not documented?

Thanks in advance for any insights!

GPIO(pin, "preserve") is not working on raspberry pi zero

Following command is not working on a raspberry pi zero:

local gpio_10 = GPIO(10, "preserve")

Following error is thrown:

GPIO_ERROR_IO
Error: Writing GPIO 'value': Operation not permitted [errno 1]

But when I open the pin 10 with "out" for the first time, I can open it after that with "preserve" without any error.
The lua script is executed from a nginx web server, using the libnginx_mod_http_lua module with the user www-data. The user www-data belongs to the gpio group.

Here is the lua code:

local GPIO = require('periphery').GPIO

local gpio_10 = GPIO(10, "preserve")
local value = gpio_10:read()
status, err = pcall(function() gpio_10:write(not value) end)
if status==false then
        value = tostring(err)
end
gpio_10:close()

local file = io.open("/var/www/html/lua/index.html","r")
local tmp = file:read("*a")
file:close(file)

tmp = tmp:gsub("$$HEAD","Raspberry Pi Zero GPIO test")
tmp = tmp:gsub("$$PIN10",tostring(value))

ngx.say(tmp)

Serial data type

If I wanted to receive the data in float format instead of string, I'd have to manually convert the bits or change the source and compile it myself right? Or is there a way

Is there something I can just drop onto a raspberry pi zero?

I'm using a Keybow MINI on a raspberry pi zero w, which has a very stripped-down OS and is difficult to connect to. You add files to it by just dropping them onto the sd card. I want to add a passive buzzer, and this looks promising. What's the best way to get something I can just drop onto the sd card and use from lua?

Lacking PWM feature

I've noticed that although the Python version has PWM capabilities, the Lua version don't count with it. Is this due to some limitation in the Language or just wasn't implemented? If so, is this something on a future milestone?

Multiple GPIO reads fail

As I understand GPIO ports, once opened, should be able to be read from or written to multiple times. But for reading only the first read works.

# lua
Lua 5.1.5  Copyright (C) 1994-2012 Lua.org, PUC-Rio (double int32)
> GPIO = require("periphery").GPIO
> gpio = GPIO(22, "in")
> print(gpio:read())
false
> print(gpio:read())
(error object is not a string)
>

Build fails on Sparc/Sparc64

Hello,

I already reported this issue (and sent a patch to fix it on c-periphery), but it still affects version 1.0.6 of lua-periphery: the build fails on sparc due to certain high baudrates not being supported. See http://autobuild.buildroot.org/results/c2f/c2fd64ed2f17c53a4704284a8281305f97a48169/build-end.log for an example of build failure.

It is probably just a matter of updating the c-periphery submodule used by lua-periphery, and doing a new lua-periphery release. The c-periphery commit fixing the issue is vsergeev/c-periphery@114c715.

Thanks!

Lua5.3: undefined symbol: luaL_checkunsigned

When running "require('periphery')" i get the following error message:

error loading module 'periphery' from file '/usr/local/lib/lua/5.3/periphery.so'
        /usr/local/lib/lua/5.3/periphery.so: undefined symbol: luaL_checkunsigned
stack traceback:
        [C]: in ?
        [C]: in function 'require'
        stdin:1: in main chunk
        [C]: in ?

I am using a raspberry pi running rasbian and Lua 5.3.0.
Periphery is installed with luarocks.
When running the instruction from Lua 5.2.4, I get no errors.

Script Error

This what i have:
function setUniform(job, playerPed)
TriggerEvent('skinchanger:getSkin', function(skin)
if skin.sex == 0 then
if Config.Uniforms[job].male ~= nil then
TriggerEvent('skinchanger:loadClothes', skin, Config.Uniforms[job].male)
else
ESX.ShowNotification(_U('no_outfit'))
end

		if job == 'bullet_wear' or job == 'fardacoletea_wear' or job == 'fardacoleteb_wear' or  job == 'fardagoea_wear' or job == 'fardagoeb_wear' then
			SetPedArmour(playerPed, 100)
		end
	else
		if Config.Uniforms[job].female ~= nil then
			TriggerEvent('skinchanger:loadClothes', skin, Config.Uniforms[job].female)
		else
			ESX.ShowNotification(_U('no_outfit'))
		end

		if job == 'bullet_wear' or job == 'fardacoletea_wear' or job == 'fardacoleteb_wear' or  job == 'fardagoea_wear' or job == 'fardagoeb_wear' then
			SetPedArmour(playerPed, 100)
		end
	end
end)

end
And this is the error
dadawda

Poll multiple GPIOs

Hello Vanya,
is there a solution to poll() multiple GPIOs at a time?
I tried to poll() via luaposix, but that doesn´t seem to work...

Serial read hang

If I attempt a read on the serial device with a timeout set, after pulling out the USB cable, then the read hangs. If the USB cable has been pulled out, then the serial port should have closed and read should give an error, or at least time out and return no data.

The problem here is that closing the USB serial device seems to result in a hang that can only be fixed by closing the program. USB port closing down needs to be detectable so the user can do something about it.

Under linux, a brief USB disconnect will move the device to the next COM port - which is hard to detect and fix without error messages.

sh: 1: make: not found when installing with LuaRocks?

Hi! I'm new to Lua, and I was trying to install lua-periphery, but I get the following error:
Installing with: sudo luarocks install lua-periphery

Installing https://luarocks.org/lua-periphery-2.3.1-1.src.rock
Warning: variable CFLAGS was not passed in build_variables
sh: 1: make: not found

Am I doing something wrong?

On Ubuntu20.04 Desktop.

The previous commands I ran to start were:

sudo apt-get update
sudo apt-get install lua5.1
sudo apt-get install liblua5.1-0-dev
sudo apt-get install lua-socket
sudo apt-get install luarocks
sudo luarocks install luasocket

Thanks!

Can i2c support write operation ?

Hello

I would like to use this library to handle eeprom with Lua. I would like to know how to write data into eeprom via Lua api ? I did not see any write operation I2C Message Flags. Thanks

Compile error on Raspbian

Hi,

I'm getting the following error when compiling on a Raspberry PI 2 with Raspbian.

In file included from src/i2c.c:21:0:
/usr/include/linux/i2c-dev.h:37:8: error: redefinition of ‘struct i2c_msg’
struct i2c_msg {
^~~~~~~
In file included from src/i2c.c:20:0:
/usr/include/linux/i2c.h:68:8: note: originally defined here
struct i2c_msg {
^~~~~~~
In file included from src/i2c.c:21:0:
/usr/include/linux/i2c-dev.h:89:7: error: redefinition of ‘union i2c_smbus_data’
union i2c_smbus_data {
^~~~~~~~~~~~~~
In file included from src/i2c.c:20:0:
/usr/include/linux/i2c.h:131:7: note: originally defined here
union i2c_smbus_data {

It happens with both Luarocks, and via source compilation. Any ideas?

Thanks in advance.

-dev

error object is not a string

local Serial = require('periphery').Serial
if Serial==nil then
print("load sdk periphery faild.");
os.exit();
end
local serial = Serial("/dev/ttyUSB0", 9600)

[Finished in 0.0s with exit code 1]/usr/local/bin/lua: (error object is not a string)

error error

The error is raised because I didn't sudo lua. If I do, periphery works fine except that errors have an issue:
$ lua
Lua 5.1.5 Copyright (C) 1994-2012 Lua.org, PUC-Rio

periphery = require('periphery')
GPIO = periphery.GPIO
i = GPIO(23, 'in')
(error object is not a string) <-- here is the problem
=periphery.version
1.0.4

Pi 2, Raspian

Adjust build system to support an external c-periphery

Currently, the build system of lua-periphery automatically clones and builds the c-periphery library by itself. While this is probably practical for some users, it is not practical at all for embedded Linux build systems such as Buildroot.

Such build systems really like to ensure that they download all the source code they build, in order to guarantee that the system can be rebuilt in the exact same state from an offline (i.e not Internet connected) machine. What lua-periphery does is currently breaking this assumption.

Would it be possible to introduce an option to the Makefile to support using an already built c-periphery library?

You can look at http://patchwork.ozlabs.org/patch/473047/ for the two patches I've proposed to Buildroot to solve the problem. Of course, those patches break the current clone+build mechanism, so a better solution will be needed for upstream lua-periphery.

Opening PWM: opening 'export': No such file or directory [errno 2]

Trying to use the pwm module and am getting this error.
This is my code up to the error.

local PWM = require('periphery').PWM
local pwm
local success,err = pcall(function() pwm = PWM(0, 22) end)
print(success,err)
false Opening PWM: opening 'export': No such file or directory [errno 2]

Im using a Raspberry Pi Model B Plus Rev 1.2 running the latest Raspbian os

error in cross-compile by yocto generated sdk

I am trying to cross-compile lua-periphery by the SDK generated by yocto for me.

but I face this error:

make[1]: Entering directory '/home/milad/git/lua-periphery/c-periphery' arm-angstrom-linux-gnueabi-gcc -O2 -pipe -g -feliminate-unused-debug-types -std=gnu99 -pedantic -Wall -Wextra -Wno-unused-parameter -fPIC -DPERIPHERY_VERSION_COMMIT=\"v2.1.0\" -Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed -c src/gpio.c -o obj/gpio.o src/gpio.c:10:20: fatal error: stdlib.h: No such file or directory #include <stdlib.h>

I found the root cause. in the makefile, CC and AR are defined for CROSS_COMPILE but for yocto SDK, defining them is not needed because they are defined in its environment-setup file.

error in installation

Window 10 with luarocks up to date and stuff
NMAKE : fatal error U1052: file 'Makefile.win' not found
Stop.

Error: Build error: Failed building.

Why...

Reading GPIO is extremely slow

I was benchmarking the speed of reading GPIO ports in different ways, and with lua-periphery it is extremely slow (using one open per read, because of #10).

GPIO = require("periphery").GPIO
OUTPUT = "out"
INPUT = "in"

--local gpio = GPIO(22, INPUT)  -- XXX: issue #10
c = 0
while (c < 100000) do
  --local data = gpio:read()  -- XXX: issue #10
  local data = GPIO(22, INPUT):read()
  c = c + 1
end
--gpio:close()  -- XXX: issue #10
  • benchmark lua-periphery (above code): real 1m 28.49s, user 0m 28.12s, sys 0m 59.36s
  • benchmark with pure Lua /sys/.. file reading (using one open per read): real 0m 8.80s, user 0m 3.83s, sys 0m 4.92s
  • benchmark with pure Lua /sys/.. file reading (open once, read and seek multiple times): real 0m 5.26s, user 0m 3.08s, sys 0m 2.18s

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.