Giter Site home page Giter Site logo

Comments (18)

zuckschwerdt avatar zuckschwerdt commented on August 28, 2024

There is no workflow in PDV to go from a WAV file to anything else, you can just look at it.

If you start with a .cu8 file (try rtl_433 -S all to get some) then you will get a pulse decoding if there are pulses in the file.

from rtl_433.

OevreFlataeker avatar OevreFlataeker commented on August 28, 2024

Thanks... I feared you'd say that :-( The thing is: when all I have is such a wav file with clear pulses (see attachment), how can I more or less comfortably parse it (like in that UI). Do you know any such tool?

I also tried Universal Radio Hacker which works fine if I do an IQ recording but those are so incredibly large and I cannot say upfront how long it might take until that message gets send/received.

Can I use rtl_433 to basically record everything in a sensible way if all I know the frequency and that it is AM OOK? Or would I always need the equivalent of an IQ recording if I cannot say upfront how my signal will look like exactly? Can I instruct rtl_433 to only record once RSSI is > value X to minimize the recording file size?

from rtl_433.

zuckschwerdt avatar zuckschwerdt commented on August 28, 2024

rtl_433 will only record signals, not noise. See -S. Usually a cu8 signal recording is 128kB.
If you really don't care about the true signal then try rtl_433 -w OOK:- or more likely rtl_433 -w mydata.ook
Also try the web UI with -F http go to http://127.0.0.1:8433/ and select "Modes" / "Raw (all)".

from rtl_433.

OevreFlataeker avatar OevreFlataeker commented on August 28, 2024

Awesome! Thank you very much! TIL rtl_433 has a webuI?!?!? :-O :-D Thanks I'll certainly try those suggestions!

Just wondering: What I originally wanted - to get the signal straight from a WAV file (some sent, uploaded, ...) - isn't this possible too? None of the tools I used so far seem to offer this possibility and I am wondering why this is. Maybe I have the wrong idea of how this is performed and it's just not possible with a simple WAV file?

from rtl_433.

zuckschwerdt avatar zuckschwerdt commented on August 28, 2024

WAV is just a container. We could be talking about the contained raw samples, Mono, 16bit, 48k could be a representation of AM (or FM) demodulated data (and rtl_433 can read raw .s16.am files). But 48k is a decimation to 20 µs per sample, we usually deal with higher rates and the filters and algorithms are tuned to that. Not sure if 48k AM data will be usable.

from rtl_433.

OevreFlataeker avatar OevreFlataeker commented on August 28, 2024

Yes, you are right ofc, that technically we should talk about the samples in the WAV not the WAV itself. I tried your suggestions with my minimalistic Arduino sketch.

//New transmission method.
//In addition, the gdo0 and gdo2 pin are not required.
//https://github.com/LSatan/SmartRC-CC1101-Driver-Lib
//by Little_S@tan
#include <ELECHOUSE_CC1101_SRC_DRV.h>

byte transmitt_byte[11] = {72,101,108,108,111,32,87,111,114,108,100};
char *transmitt_char = "Hello World";

void setup() {

    Serial.begin(9600);

    if (ELECHOUSE_cc1101.getCC1101()){      // Check the CC1101 Spi connection.
    Serial.println("Connection OK");
    }else{
    Serial.println("Connection Error");
    }
 
    ELECHOUSE_cc1101.Init();                // must be set to initialize the cc1101!
    ELECHOUSE_cc1101.setCCMode(1);          // set config for internal transmission mode.
    ELECHOUSE_cc1101.setModulation(2);      // set modulation mode. 0 = 2-FSK, 1 = GFSK, 2 = ASK/OOK, 3 = 4-FSK, 4 = MSK.
    ELECHOUSE_cc1101.setMHZ(433.92);        // Here you can set your basic frequency. The lib calculates the frequency automatically (default = 433.92).The cc1101 can: 300-348 MHZ, 387-464MHZ and 779-928MHZ. Read More info from datasheet.
    ELECHOUSE_cc1101.setDeviation(47.6);   // Set the Frequency deviation in kHz. Value from 1.58 to 380.85. Default is 47.60 kHz.
    ELECHOUSE_cc1101.setChannel(0);         // Set the Channelnumber from 0 to 255. Default is cahnnel 0.
    ELECHOUSE_cc1101.setChsp(199.95);       // The channel spacing is multiplied by the channel number CHAN and added to the base frequency in kHz. Value from 25.39 to 405.45. Default is 199.95 kHz.
    ELECHOUSE_cc1101.setRxBW(812.50);       // Set the Receive Bandwidth in kHz. Value from 58.03 to 812.50. Default is 812.50 kHz.
    //ELECHOUSE_cc1101.setDRate(99.97);       // Set the Data Rate in kBaud. Value from 0.02 to 1621.83. Default is 99.97 kBaud!
    ELECHOUSE_cc1101.setDRate(5);
    ELECHOUSE_cc1101.setPA(10);             // Set TxPower. The following settings are possible depending on the frequency band.  (-30  -20  -15  -10  -6    0    5    7    10   11   12) Default is max!
    ELECHOUSE_cc1101.setSyncMode(2);        // Combined sync-word qualifier mode. 0 = No preamble/sync. 1 = 16 sync word bits detected. 2 = 16/16 sync word bits detected. 3 = 30/32 sync word bits detected. 4 = No preamble/sync, carrier-sense above threshold. 5 = 15/16 + carrier-sense above threshold. 6 = 16/16 + carrier-sense above threshold. 7 = 30/32 + carrier-sense above threshold.
    ELECHOUSE_cc1101.setSyncWord(211, 145); // Set sync word. Must be the same for the transmitter and receiver. (Syncword high, Syncword low)
    ELECHOUSE_cc1101.setAdrChk(0);          // Controls address check configuration of received packages. 0 = No address check. 1 = Address check, no broadcast. 2 = Address check and 0 (0x00) broadcast. 3 = Address check and 0 (0x00) and 255 (0xFF) broadcast.
    ELECHOUSE_cc1101.setAddr(0);            // Address used for packet filtration. Optional broadcast addresses are 0 (0x00) and 255 (0xFF).
    ELECHOUSE_cc1101.setWhiteData(0);       // Turn data whitening on / off. 0 = Whitening off. 1 = Whitening on.
    ELECHOUSE_cc1101.setPktFormat(0);       // Format of RX and TX data. 0 = Normal mode, use FIFOs for RX and TX. 1 = Synchronous serial mode, Data in on GDO0 and data out on either of the GDOx pins. 2 = Random TX mode; sends random data using PN9 generator. Used for test. Works as normal mode, setting 0 (00), in RX. 3 = Asynchronous serial mode, Data in on GDO0 and data out on either of the GDOx pins.
    ELECHOUSE_cc1101.setLengthConfig(1);    // 0 = Fixed packet length mode. 1 = Variable packet length mode. 2 = Infinite packet length mode. 3 = Reserved
    ELECHOUSE_cc1101.setPacketLength(0);    // Indicates the packet length when fixed packet length mode is enabled. If variable packet length mode is used, this value indicates the maximum packet length allowed.
    ELECHOUSE_cc1101.setCrc(1);             // 1 = CRC calculation in TX and CRC check in RX enabled. 0 = CRC disabled for TX and RX.
    ELECHOUSE_cc1101.setCRC_AF(0);          // Enable automatic flush of RX FIFO when CRC is not OK. This requires that only one packet is in the RXIFIFO and that packet length is limited to the RX FIFO size.
    ELECHOUSE_cc1101.setDcFilterOff(0);     // Disable digital DC blocking filter before demodulator. Only for data rates ≤ 250 kBaud The recommended IF frequency changes when the DC blocking is disabled. 1 = Disable (current optimized). 0 = Enable (better sensitivity).
    ELECHOUSE_cc1101.setManchester(1);      // Enables Manchester encoding/decoding. 0 = Disable. 1 = Enable.
    ELECHOUSE_cc1101.setFEC(0);             // Enable Forward Error Correction (FEC) with interleaving for packet payload (Only supported for fixed packet length mode. 0 = Disable. 1 = Enable.
    ELECHOUSE_cc1101.setPRE(0);             // Sets the minimum number of preamble bytes to be transmitted. Values: 0 : 2, 1 : 3, 2 : 4, 3 : 6, 4 : 8, 5 : 12, 6 : 16, 7 : 24
    ELECHOUSE_cc1101.setPQT(0);             // Preamble quality estimator threshold. The preamble quality estimator increases an internal counter by one each time a bit is received that is different from the previous bit, and decreases the counter by 8 each time a bit is received that is the same as the last bit. A threshold of 4∙PQT for this counter is used to gate sync word detection. When PQT=0 a sync word is always accepted.
    ELECHOUSE_cc1101.setAppendStatus(0);    // When enabled, two status bytes will be appended to the payload of the packet. The status bytes contain RSSI and LQI values, as well as CRC OK.

    Serial.println("Tx Mode");
}

void loop() {

//3 different methods to send data without gdo
//When sending, we give a little time to completely transmit the message (time in millis).
//You can shorten the time. It depends on the data rate and the packet length. Just try it out for fine tuning.

//Transmitt "Hello World" from byte format.
ELECHOUSE_cc1101.SendData(transmitt_byte, 11, 100);
delay(2000);

//Transmitt "Hello World" from char format.
ELECHOUSE_cc1101.SendData(transmitt_char, 100);
delay(2000);

//Transmitt "Hello World" from char format directly.
ELECHOUSE_cc1101.SendData("Hello World", 100);
delay(2000);
}

These are my findings:
Plain AM modulation of data with Manchester in DRate 5 - save bet: Works like a charm:

Detected OOK package	2024-05-31 20:45:10
Analyzing pulses...
Total count:  104,  width: 57.90 ms		(14475 S)
Pulse width distribution:
 [ 0] count:   63,  width:  216 us [216;240]	(  54 S)
 [ 1] count:   41,  width:  416 us [416;444]	( 104 S)
Gap width distribution:
 [ 0] count:   41,  width:  380 us [368;384]	(  95 S)
 [ 1] count:   62,  width:  180 us [180;184]	(  45 S)
Pulse period distribution:
 [ 0] count:   37,  width:  600 us [596;608]	( 150 S)
 [ 1] count:   22,  width:  800 us [796;808]	( 200 S)
 [ 2] count:   44,  width:  400 us [400;404]	( 100 S)
Pulse timing distribution:
 [ 0] count:  125,  width:  200 us [180;240]	(  50 S)
 [ 1] count:   82,  width:  400 us [368;444]	( 100 S)
 [ 2] count:    1,  width: 10004 us [10004;10004]	(2501 S)
Level estimates [high, low]:  16007,     15
RSSI: -0.1 dB SNR: 30.3 dB Noise: -30.4 dB
Frequency offsets [F1, F2]:    9830,      0	(+37.5 kHz, +0.0 kHz)
Guessing modulation: Manchester coding
view at https://triq.org/pdv/#AAB10300C801902714819191919191919190819180908081809180809180808091908191809180808090818091919081908180809081908180809081908080818091808080808091919080819081908080819080818091809081908180809081809180808080919190808080808080819255
Attempting demodulation... short_width: 216, long_width: 0, reset_limit: 388, sync_width: 0
Use a flex decoder with -X 'n=name,m=OOK_MC_ZEROBIT,s=216,l=0,r=388'
[pulse_slicer_manchester_zerobit] Analyzer Device
codes     : {145}2aaad3910b48656c6c6f20576f726c6415fe8

(Format is aaaa (preamble), 3910 (syncword), 0x0b = Length of data, date = 'Hello world', CRC)
Without Manchester rtl_433 cannot properly decode it, switching to FSK also does not improve the decoding.

I am still trying to understand if my code (based on library samples) is wrong or I am using combination of parameters (AM/too fast/...) which inhibits the decoding.

Nevertheless, using the S option and the variations you provided above I am confident I will be able to decode proper unknown signals and not my self-generated test code. Thank you very much.

If you are able to see what I am doing wrong in my attempts with setModulation(0) (FM) - no demodulation is possible for rtl_433 no matter how fast or slow (parameter setDRate) I send or whether I use Manchester or not (setManchester(1)). Also without Manchester but ASK/OOK (setModulation(2)) I can only get corrupted/parted decodings.

from rtl_433.

zuckschwerdt avatar zuckschwerdt commented on August 28, 2024

I don't readily know CC1101 registers. MC isn't usually seen with OOK. Plain PWM should work (but you might need to encode it yourself e.g. 0-bit -> 1000, 1-bit -> 1110), PCM might not work well if you have long runs of 0's or 1's.
Upload .cu8 samples (from -S) and we can take a look why it won't decode. Usually FSK works best with -Y minmax (default at e.g. 868M).

from rtl_433.

OevreFlataeker avatar OevreFlataeker commented on August 28, 2024

Thank you very much for your offer to have a look. Please keep in mind that I am in no way claiming that is an issue with rtl_433 but pretty sure it's about how I use the sample code. Nevertheless I´d like to understand the underlying reason WHY it cannot properly be decoded, if that is extractable from the files in order to understand everything better. When I am going to sniff signals from a "real" device I'm pretty sure those issues won´t turn up, as those developers probably know how to do it the right way ;-)

Why I am stressing the point with those samples? When I have some unknown signals, I want to have confidence which options I have, where I can tweak, how can I massage the pulses in order to try to get a proper decoding. My idea was to send some known data (i.e my HelloWorld sketch above in various modifications) so I KNOW what to have as a result and have a correlation like "Ok, when it's FSK I need to tweak this and that, or when it's send very slow I need to do this and that, etc." - so just getting some experience by trying to get results known in advance ;-)

In the attached samples, the decoded output should always be "2aaad3910b48656c6c6f20576f726c6415fe8" as above. I've changed a) modulation, b) datarate, c) manchester on/off, d) timeout for send

All files saved via ¨rtl_433 -S unknown" with default settings


ASK/OOK examples:

1.
ASK/OOK, DRate=5, Manchester=1
ask_ook_manchester_5.cu8

2.
ASK/OOK, DRate=5, Manchester=0
ask_ook_no_manchester_5.cu8
ask_ook_no_manchester_5_2nd.cu8
(rtl_433 repeatedly created alternating files with 43981 and 43971 samples)

3.
ASK/OOK, DRate=99.97, Manchester=1
ask_ook_manchester_99.cu8

4.
ASK/OOK, DRate=99.97, Manchester=0
ask_ook_nomanchester_99.cu8
ask_ook_nomanchester_99_2nd.cu8
(rtl_433 repeatedly created files with different num of samples)

FSK examples:

1.
2-FSK, DRate=5, Manchester=1
fsk_manchester_5.cu8

2. 
2-FSK, DRate=5, Manchester=0
fsk_nomanchester_5.cu8

3.
2-FSK, DRate=99.97, Manchester=1
fsk_manchester_99.cu8

4.
2-FSK, DRate=99.97, Manchester=0
fsk_nomanchester_99.cu8

-- 
After I created those 8 examples, I noticed that the SendData routine had a timeout of 100ms and wondered if that might be the reason the very slow transmissions are all corrupted, so I did two more with timeout 1000.
SendData with timeout 1000:

ASK/OOK, DRate=5, NoManchester
ask_ook_nomanchester_5_1000.cu8

2-FSK, DRate=5, NoManchester
fsk_nomanchester_5_1000.cu8

simple_samples.zip

from rtl_433.

zuckschwerdt avatar zuckschwerdt commented on August 28, 2024

DR 99 -- too fast for the sample rate, zoom in with https://triq.org/spectrogram-next/ and you'll see it's barely two samples per bit.
Note that ASK is OOK (or rather simple 2-ASK is). You can't have _ook_ in the file name, it is treated as .ook. which is meta data info about the format.

FSK -- the deviation seems massive. We usually see much less, maybe 10k to 30k.

That aside the files seem to read well with rtl_433 -Y minmax -A

Also note that all files are clipping (too loud) and the gain should be lower or distance to antenna greater.

from rtl_433.

OevreFlataeker avatar OevreFlataeker commented on August 28, 2024

Re DR: Ok, assumed so. Using URH I also saw that basically the whole messag was send within one period of the carrier(?) wave and I had errors the moment the wave has a zero point. That's why I was starting with lowering the DR and saw with 5 or 20 it was good. Could I just increase the sample rate to a much higher value with rtl_433? Would that alone make the signal properly decodeable?

Re OOK in filename: Oh, I didn´t know that. Thanks for mentioning.

FSK: What do you mean by deviation. The value for

" ELECHOUSE_cc1101.setDeviation(47.6); // Set the Frequency deviation in kHz. Value from 1.58 to 380.85. Default is 47.60 kHz."

? I read that this would offset the sending base frequency to avoid collisions. But I also noticed, setting this to 0 so it will send at exactly at 433.92 MHz, does not send anything at all. So this is how far the FM actually changes?
Can I make rtl_433 support 47.6 kHz as well or would I need to change this in the code?

"That aside the files seem to read well with rtl_433 -Y minmax -A"
So you can read and decode them all? In all variations?

Gain: Yes, sender and SDR are on the same table. Will try again.

from rtl_433.

OevreFlataeker avatar OevreFlataeker commented on August 28, 2024

For "ask_ook_nomanchester_5_1000.cu8" (original, now renamed to have nomore ook in the filename) I get

daubsi@s935:~/Downloads/rtl_433$ ./rtl_433 -r ask_nomanchester_5_1000.cu8 -A
rtl_433 version -128-NOTFOUND branch  at 202404231952 inputs file rtl_tcp RTL-SDR with TLS
[Input] Test mode active. Reading samples from file: ask_nomanchester_5_1000.cu8
Detected OOK package	@0.151796s
Analyzing pulses...
Total count:   41,  width: 28.65 ms		( 7162 S)
Pulse width distribution:
 [ 0] count:   23,  width:  216 us [216;236]	(  54 S)
 [ 1] count:   12,  width:  416 us [412;424]	( 104 S)
 [ 2] count:    3,  width:  616 us [616;616]	( 154 S)
 [ 3] count:    2,  width:  820 us [820;820]	( 205 S)
 [ 4] count:    1,  width: 1616 us [1616;1616]	( 404 S)
Gap width distribution:
 [ 0] count:   24,  width:  180 us [176;188]	(  45 S)
 [ 1] count:    8,  width:  380 us [376;388]	(  95 S)
 [ 2] count:    4,  width:  580 us [580;584]	( 145 S)
 [ 3] count:    2,  width:  784 us [784;784]	( 196 S)
 [ 4] count:    2,  width: 1084 us [984;1184]	( 271 S)
Pulse period distribution:
 [ 0] count:   15,  width:  400 us [400;412]	( 100 S)
 [ 1] count:   10,  width:  600 us [596;604]	( 150 S)
 [ 2] count:   10,  width: 1040 us [996;1200]	( 260 S)
 [ 3] count:    4,  width:  800 us [800;800]	( 200 S)
 [ 4] count:    1,  width: 1404 us [1404;1404]	( 351 S)
Pulse timing distribution:
 [ 0] count:   47,  width:  200 us [176;236]	(  50 S)
 [ 1] count:   20,  width:  400 us [376;424]	( 100 S)
 [ 2] count:    7,  width:  596 us [580;616]	( 149 S)
 [ 3] count:    5,  width:  836 us [784;984]	( 209 S)
 [ 4] count:    1,  width: 1616 us [1616;1616]	( 404 S)
 [ 5] count:    1,  width: 1184 us [1184;1184]	( 296 S)
 [ 6] count:    1,  width: 16164 us [16164;16164]	(4041 S)
Level estimates [high, low]:  16004,    466
RSSI: -0.1 dB SNR: 15.4 dB Noise: -15.5 dB
Frequency offsets [F1, F2]:   10667,      0	(+40.7 kHz, +0.0 kHz)
Guessing modulation: No clue...
view at https://triq.org/pdv/#AAB01D070100C8019002540344065004A03F2480808080808080809081A1828355+AAB014070100C8019002540344065004A03F248090818355+AAB01A070100C8019002540344065004A03F249180809092909290B18555+AAB01B070100C8019002540344065004A03F248080A090B0A1819092918355+AAB013070100C8019002540344065004A03F248080C655

Same result also with -Y minmax.
Did this work for you?

For all the FSK examples I did not get any decoding with -A -Y minmax for any sample file. Is this due to the deviation, that is too high in my example code?

from rtl_433.

zuckschwerdt avatar zuckschwerdt commented on August 28, 2024

Re DR, here I meant sample literally. There are about two I/Q pairs per bit. You need to raise the sample rate to get oversampling by at least 20 (i.e. one bit should last 20 samples).

Yes, FSK deviation is the offset between both carriers. 50k should be fine too, it just looks pretty wide.

If you send at exactly 433.92 MHz then record at some offset, e.g. 433.85M. Assume that the receiver is deaf at the exact center frequency.

E.g.

Pulse width distribution:
 [ 0] count:   23,  width:  216 us [216;236]	(  54 S)
 [ 1] count:   12,  width:  416 us [412;424]	( 104 S)
 [ 2] count:    3,  width:  616 us [616;616]	( 154 S)
 [ 3] count:    2,  width:  820 us [820;820]	( 205 S)
 [ 4] count:    1,  width: 1616 us [1616;1616]	( 404 S)

That looks good. All the multiples of 200 µs are the runs of bits. Examine the pdv link to see.

from rtl_433.

OevreFlataeker avatar OevreFlataeker commented on August 28, 2024

Which PDF do you mean please?

I now tried Modulation=0 (2-FSK), SetDeviation(15) (and also the original value), setPA (Power) to -12.
With -12 and deviation of 15kHz I now get a sure demodulation... But it now also works with a deviation of the default of 47 kHz. And also some times with Power back to +10. But -12 seems to be better. So the receiver is kind of overloaded with +10 and the signal gets clipped I assume? Is this probably why I had no success until now?

Deafness at center: As far as I know this is only an issue with the E4000 tuner, but not with R828?

from rtl_433.

OevreFlataeker avatar OevreFlataeker commented on August 28, 2024

Where did you see the samples were clipping initially? Which value do I need to have an eye on?

Is it the RSSI?

RSSI: -0.1 dB SNR: 20.2 dB Noise: -20.4 dB

The values don´t seem to change though when I change the output power...

I am right now experimenting with the settings, increasing speed/sample rate, etc. Do you know what the maximum sample rate is for the RTL-SDR Blog v4? It seems I cannot set it to > 300.000 Hz? (Error cannot set to ...)

from rtl_433.

zuckschwerdt avatar zuckschwerdt commented on August 28, 2024

pdv, https://triq.org/pdv/ sorry, edited.

Yes, clipping will be a big problem for rtl_433. Or demod needs to find (part of) a sine wave to work. (The algorithm uses instant phase angle measurements.)

The center frequency is represented a 0 Hz there can be no meaningful signal at 0 Hz. Examine a signal ever closer to 0 Hz (i.e. 433.92 MHz with the defaults) in https://triq.org/spectrogram-next/ by looking at the bottom waveform display in full zoom.

For clipping look for red areas in the small amplitude bar in https://triq.org/spectrogram-next/

For sample rates try 1024k and maybe 2048k (or 2000k). Up to 3072k should be supported but the receiver will get pretty hot and needs cooling usually.

from rtl_433.

OevreFlataeker avatar OevreFlataeker commented on August 28, 2024

Could you kindly explain how to read this?

Pulse width distribution:
 [ 0] count:   23,  width:  216 us [216;236]	(  54 S)
 [ 1] count:   12,  width:  416 us [412;424]	( 104 S)
 [ 2] count:    3,  width:  616 us [616;616]	( 154 S)
 [ 3] count:    2,  width:  820 us [820;820]	( 205 S)
 [ 4] count:    1,  width: 1616 us [1616;1616]	( 404 S)

You wrote: "All the multiples of 200 µs are the runs of bits".
What do the numbers in square brackets mean (first pos and after width)
Is the second the range of all values and width the avg?
Whats the last number in ( ) ? (54 S, 104 S, ...)
Assuming the first [ ] gives the number of consecutive pulses. Shouldn´t be "[4]" then be around 1016 instead of 1616? Shouldn´t [3] be 816 instead of 820 (though I assume this might be due to a measurement error due to the very short duration?)

from rtl_433.

zuckschwerdt avatar zuckschwerdt commented on August 28, 2024

Yes. In order: average, range (in brackets, µs), average in number of samples.

from rtl_433.

gdt avatar gdt commented on August 28, 2024

Please ask on the list or open a discussion; this is not a valid bug as it stands. (And the issue tracker is overwhelmed.)

from rtl_433.

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.