Quantcast
Channel: 懒得折腾
Viewing all 764 articles
Browse latest View live

ArduinoLibs Cryptographic Library

$
0
0
Cryptographic Library

Supported Algorithms

All cryptographic algorithms have been optimized for 8-bit Arduino platforms like the Uno. Memory usage is also reduced, particularly for SHA1, SHA256, and SHA512 which save 256, 192, and 512 bytes respectively over traditional implementations. For all algorithms, static sbox tables and the like are placed into program memory to further reduce data memory usage.

ChaCha with 20 rounds and 256-bit keys is the recommended symmetric encryption algorithm because it is twice as fast as AES128, constant-time, and much more secure. AES128, AES192, and AES256 are provided for use in applications where compatibility with other systems is desirable.

If code size is an issue for your application (for example on very low end Arduino variants), then Speck on AVR is less than half the code size of ChaCha, at the cost of more data memory for the state and longer key setup times. The SpeckLowMemory class is even smaller at the cost of some performance when encrypting.

BLAKE2s and BLAKE2b are variations on the ChaCha stream cipher, designed for hashing, with 256-bit and 512-bit hash outputs respectively. They are intended as high performance replacements for SHA256 and SHA512 for when speed is critical but exact bit-compatibility of hash values is not.

Examples and other topics

Performance

Performance on AVR

All figures are for the Arduino Uno running at 16 MHz. Figures for the Ardunino Mega 2560 running at 16 MHz are similar:

Encryption Algorithm Encryption (per byte) Decryption (per byte) Key Setup State Size (bytes)
AES128 (ECB mode) 36.90us 66.48us 160.00us 213
AES192 (ECB mode) 44.20us 80.35us 166.54us 245
AES256 (ECB mode) 51.50us 94.22us 227.97us 277
ChaCha (20 rounds) 14.87us 14.88us 43.74us 132
ChaCha (12 rounds) 10.38us 10.38us 43.74us 132
ChaCha (8 rounds) 8.13us 8.14us 43.74us 132
Speck (128-bit key, ECB mode) 10.72us 11.09us 287.02us 275
Speck (192-bit key, ECB mode) 11.03us 11.42us 298.21us 275
Speck (256-bit key, ECB mode) 11.35us 11.74us 309.66us 275
SpeckLowMemory (128-bit key, ECB mode) 35.25us 10.22us 35
SpeckLowMemory (192-bit key, ECB mode) 36.56us 13.62us 35
SpeckLowMemory (256-bit key, ECB mode) 37.87us 16.89us 35
AEAD Algorithm Encryption (per byte) Decryption (per byte) Key Setup State Size (bytes)
ChaChaPoly 41.23us 41.23us 902.55us 255
GCM<AES128> 186.47us 186.42us 1388.43us 316
GCM<AES192> 194.17us 193.72us 1628.67us 348
GCM<AES256> 201.47us 201.02us 1923.78us 380
Hash Algorithm Hashing (per byte) Finalization State Size (bytes)
SHA1 21.90us 1423.28us 95
SHA256 43.85us 2841.04us 107
SHA512 122.82us 15953.42us 211
SHA3_256 121.69us 16486.33us 405
SHA3_512 229.12us 16502.34us 405
BLAKE2s 18.54us 1200.06us 171
BLAKE2b 50.70us 6515.87us 339
Authentication Algorithm Hashing (per byte) Finalization Key Setup State Size (bytes)
SHA1 (HMAC mode) 21.90us 4296.33us 1420.24us 95
SHA256 (HMAC mode) 43.85us 8552.61us 2836.49us 107
BLAKE2s (HMAC mode) 18.54us 3649.98us 1214.81us 171
Poly1305 26.29us 486.15us 17.26us 87
GHASH 148.14us 17.09us 21.87us 33
Public Key Operation Time (per operation) Comment
Curve25519::eval() 3119ms Raw curve evaluation
Curve25519::dh1() 3121ms First half of Diffie-Hellman key agreement
Curve25519::dh2() 3120ms Second half of Diffie-Hellman key agreement
Ed25519::sign() 5688ms Digital signature generation
Ed25519::verify() 9030ms Digital signature verification
Ed25519::derivePublicKey() 5642ms Derive a public key from a private key

Where a cipher supports more than one key size (such as ChaCha), the values are typically almost identical for 128-bit and 256-bit keys so only the maximum is shown above.

Performance on ARM

All figures are for the Arduino Due running at 84 MHz:

Encryption Algorithm Encryption (per byte) Decryption (per byte) Key Setup State Size (bytes)
AES128 (ECB mode) 6.65us 11.00us 35.15us 220
AES192 (ECB mode) 8.02us 13.31us 36.59us 252
AES256 (ECB mode) 9.39us 15.63 50.19us 284
ChaCha (20 rounds) 0.87us 0.88us 4.96us 136
ChaCha (12 rounds) 0.70us 0.71us 4.96us 136
ChaCha (8 rounds) 0.62us 0.62us 4.96us 136
Speck (128-bit key, ECB mode) 0.97us 0.96us 36.80us 288
Speck (192-bit key, ECB mode) 1.00us 0.98us 38.14us 288
Speck (256-bit key, ECB mode) 1.03us 1.01us 39.31us 288
SpeckLowMemory (128-bit key, ECB mode) 2.72us 1.47us 48
SpeckLowMemory (192-bit key, ECB mode) 2.81us 1.54us 48
SpeckLowMemory (256-bit key, ECB mode) 2.90us 1.83us 48
AEAD Algorithm Encryption (per byte) Decryption (per byte) Key Setup State Size (bytes)
ChaChaPoly 1.66us 1.66us 45.02us 280
GCM<AES128> 11.01us 10.92us 247.90us 344
GCM<AES192> 12.40us 12.31us 294.07us 376
GCM<AES256> 13.73us 13.64us 347.40us 408
Hash Algorithm Hashing (per byte) Finalization State Size (bytes)
SHA1 0.94us 62.55us 112
SHA256 1.15us 76.60us 120
SHA512 2.87us 370.37us 224
SHA3_256 5.36us 697.65us 424
SHA3_512 9.89us 697.81us 424
BLAKE2s 0.76us 50.88us 184
BLAKE2b 1.33us 170.93us 352
Authentication Algorithm Hashing (per byte) Finalization Key Setup State Size (bytes)
SHA1 (HMAC mode) 0.94us 193.92us 65.09us 112
SHA256 (HMAC mode) 1.15us 238.98us 80.44us 120
BLAKE2s (HMAC mode) 0.76us 165.64us 59.92us 184
Poly1305 0.85us 19.25us 2.35us 96
GHASH 4.37us 1.50us 4.37us 36
Public Key Operation Time (per operation) Comment
Curve25519::eval() 103ms Raw curve evaluation
Curve25519::dh1() 103ms First half of Diffie-Hellman key agreement
Curve25519::dh2() 104ms Second half of Diffie-Hellman key agreement
Ed25519::sign() 195ms Digital signature generation
Ed25519::verify() 306ms Digital signature verification
Ed25519::derivePublicKey() 194ms Derive a public key from a private key


Introduction to EAGLE

$
0
0

Introduction to EAGLE – Part 1 – Control panel

This article is part of a tutorial dedicated to EAGLE. The reader may consult the other parts of the tutorial by following this link: Introduction to EAGLE
Eagle stands for Easily Applicable Graphical Layout Editor. It is an electronic CAD software manufactured by CadSoft Computer GmbH, a German company, since 1988. This software is provided with, among other, a schematic capture editor, a PCB (Printed Circuit Board) layout editor, an auto-router, a Computer-Aided Manufacturing (CAM)… It supports Windows, Linux and Mac OS X. This tutorial has been prepared under version 6.5.0 / Ubuntu 12.04 LTS

Control panel

When EAGLE is started, the following window appears on the screen,this is the control panel, the EAGLE starting window.ControlPanelOn the left hand side of the window the user manage existing and new projects and can get an overview about the libraries and settings :

  • Libraries: this entry lists libraries of components, each component is composed of a schematic and a footprint linked together.
  • Design Rules: the user can tune the parameters relevant to the board and its manufacture.
  • User Language Programs: this is C-like programs that can be used for a variety of tasks. It can be used, for example, to modify your project and automize certain tasks.
  • Scripts: the user can execute sequences of commands that are stored in a script file. It provides the ability to customize the program according to your own wishes (assign keys,
    load pc board shapes, change colors…)
  • CAM Jobs: CAM stands for Computer-Aided Manufacturing. It generates output data for the manufacturing tools (for exemple exporting Gerbers files which is the most used professional format).
  • Projects: this entry lists the examples and projets. When a new project is created, it is automaticaly added in the tree.

The Arduino MEGA2560 board has been designed with EAGLE. It is provided within the examples:

Arduino

Directories

Basicaly, EAGLE stores all the projects and necessary files in the same main folder and creates subfolders to differenciate each projet. In the main menu bar, select Option > Directories:

Menu_Directory

The following interface allows the user to configure directories. $EAGLEDIR represents the path to the main folder (on my installation it is located in /home/username/eagle-6.5.0/). When a new project is created, a new folder is automatically added in $EAGLEDIR/projects/ . The user can specify several folders. It is possible, for example, to have the default libraries available on a network server, and the personal projects in private local folders.

Directory

Before continuing check that the folder for libraries is configured with the following path: $EAGLEDIR\lbr.

Libraries

On the left hand side of the control panel, click on Libraries to develop the tree and select the library 74xx-eu.lbr. This library is dedicated to TTL Devices (74xx Series from Texas Instruments). Select a device, on the right side the symbol and footprint appear:

Library

New project

To create a new project, select File > New > Project :
NewProject

A new project is automatically added on the left hand side of the window under the branch Project/eagle. Enter you project name, for example FirstPCB :

ProjectNameRight click on the project and select New > Schematic.
NewSchematic

A new window is automatically open, this is the Schematic Editor:
SchematicEditor

Click here for the next step

Introduction to EAGLE – Part 2 – Schematic editor

This article is part of a tutorial dedicated to EAGLE. The reader may consult the other parts of the tutorial by following this link: Introduction to EAGLE
In this tutorial the reader will be guided to create a simple PCB, first lets start by creating the schematics.

Workspace

Before starting the schematic, lets insert a frame containing title, date, author … On the vertical tool bar located on the left side of the window, click on the ADD icon. The ADD action allows to add new item in the design. It is largely dedicated to the insertion of new components.

Add_Icon

A window pops up and display all the available libraries. In the search entry located at the bottom left of the window, type “frame” and confirm with the Enter key :
Add_Frame
The list of libraries is now limited to entries containing the string “frame” in there title or description. Select the A4L-LOC which is a DIN A4 Landscape frame and click OK. The frame is now attached to the cursor, place the frame in order to align the bottom-left corner of the frame at coordinates 0,0. Coordinates are displayed in the upper left corner of the working area. The origin is also display in the working area with a small dotted cross. When the frame is placed, left click with the mouse and hit twice the “Esc” key to exit.

Frame_Grid

Save your design and change the view by clicking on “Zoom to fit”. You should now have a general view of your future design.

ZoomToFit

Click on the grid icon:

Grid

The grid setting window appears, in this window, you can set the grid parameters (size, style, etc.). Set display “On” and click “OK”. Your workspace is prepared for the schematic and should look like this:

Workspace

Adding symbols

Click to the ADD icon as explained previously for adding the frame. EAGLE is provided with a large number of librairies, and the user can enter one or more search patterns in the search field by using special characters (wild cards) ‘?’ and ‘*’:

  • * is a search pattern that can be replaced by one or several characters. For example *555 will provide all the entries ending by 555. 555* will provide all the entries beginning by 555 and *555* will provide all the entries containing 555.
  • ? is a search pattern similar to ‘*’, excepted that it can only be replaced by a single character.

It is usefull to remember that when you add a device, right click rotate and left click place the symbol. Once a symbol is placed, several operations are still possible :

Move     Copy  RotateDelete

Search and add the following components in your design (the belonging library and package is mentioned in brackets) :

COMPONENT LIBRARY DEVICE PACKAGE
555 timer st-microelectronics NE555 DIL-08
Resistor rcl R-EU 0204/7
Polarized capacitor rcl CPOL-EU2,5-6E E2,5-6E
Capacitor rcl C-EUC1206 C1206
Screew terminal con-ptr500 AK500/2 AK500/2
5mm LED led LED5MM LED5MM
VCC supply symbol supply2 VCC
GND supply symbol supply2 GND
Note that, even if VCC and GND are provided for convience and are not real components, they can be found in the libraries. Add and place your components in order to get the following arrangement:

ComponentsPlacement

Adding connections

The electrical connections have to be drawn with the NET tool (or the bus tool for buses). The WIRE tool also draw lines, but it is not dedicated to electrical connections, it belongs to the drawing tools (text, circle, arcs…).

net

Once the NET tool is selected, add a connection by clicking on the first pin to connect. Place the cursor on the second pin or junction, and right click without moving the mouse : the wire bend style will automaticaly change. It can also be done by selecting one of the wire bend style icon:

WireBendStyle

Place the connection according to the following schematic. This is a very simple NE555-based LED blinker:

SchematicWiring

Component name and value

The following icon (NAME) allows the user to change a component name :

Name

In the same way, the VALUE icon allows the user to add or modify the component value (when applicable):

Value

Rename and set values of each symbol according to the following illustration:

Rename

Check errors

Once your schematic is finished, it is safe to use the ERC (Electric Rules Check) tool. It can detect many mistakes in the design (wrong connections, non compatible junctions …)

ERC.

A new window pops up, and displays four warnings:

ErrorList

The first one says that the pin 8 of the NE555 is called VCC+ and is connected to VCC. The three others say that the frame, the LED and the screw terminal don’t have values. As none of this four warning is an error, the four errors can be approved. The dialog box should now display zero error, zero warning and four approved:

ErrorApproved

Generating board

When the schematic is finished and checked, the board can be created. Click on the following icon to generate the board and launch the board editor.

GenerateBoard

EAGLE may ask you to confirm the creation of a new board from your schematic, answer yes and the PCB is automatically prepared for routing:

BoardEditor

Click here for the next step

Introduction to EAGLE – Part 3 – Board editor

This article is part of a tutorial dedicated to EAGLE. The reader may consult the other parts of the tutorial by following this link: Introduction to EAGLE
It is here assumed that the reader had studied the part 2 and that the schematic has been processed. The board editor should now look like this illustration:

BoardEditor

Forward and backward annotation

Check that the schematic editor and the board editors are open simultaneously. Save both designs and close the board editor. The schematic editor display the following message : “Forward and backward annotation has been severed !”:

FB_Annotation

A key element is that EAGLE maintains the link between the schematics and the PCB. When a modification is perfomed in the schematic, the PCB is immediatly updated (forward annotation). In the same way when the PCB is modified, the schematic is updated accordingly (backward annotation). It prevents the project from splitting into incompatible parts. The downside is that the designer have to consider it while working.

Workspace

The board editor environment is very similar to the schematic editor (user interface arrangement is almost the same). As it was done for the schematic editor, display a grid of 50 mils in the board editor. Now select the WIRE tool to draw the board outline. Above the working area an horizontal menu bar is displayed. This is the wire properties. Set the layer to 20 (Dimension) and select a width of 10 mils. Note that the unity of the editor is set by the unity of the grid.

WireProperties

Left-click on the origin of the working area (coordinates 0,0), now click at coordinates 1600,1000 and finaly double click anew on the origin (right click at each point while defining the outline changes the wire bend style). The board outline should now be visible in grey:

BoardOutline

It is convinient to remember that the mouse wheel allows you to zoom in and out and the middle button allows you to drag your design to another place (middle button has to be maintained pressed while moving the mouse).

Placement

As for the schematic editor, the MOVE tool is used for moving components. The view displayed in the board editor is a top view of the PCB. Item drawn with the red color are located on the top side (component side) and item drawn in blue are located on the bottom side (copper side). To transfer a component on the other side, use the MIRROR tool. Select the tool, and click close to the origin (white cross) of the component to transfert. Place C2 on the bottom side, and C3 on the top side.

Mirror

As for the schematic editor, when moving a component left-click places the component, right-click perfoms a rotation. While placing the components, it is possible to update the ratsnets (i.e. calculate the shortest airwire for each connection) by clicking on this icon:

Ratsnets

Place the components according to the following arrangement and update the ratsnet.

ComponentArrangement

Routing

Routing consists now in transforming the airwires into routed copper-made tracks. It is done with the help of the tool ROUTE:

Route

To create a new track, select the routing tool and click on the airwire you want to route. The track appears while moving the cursor. Right-click change the wire bend style as for nets in the schematic editor. Double-click ends the operation. By changing the layer above the upper left corner of the working area while routing, it switchs the track from one side to another and automaticaly add a via if necessary. You can save a lot of time using the middle button of the mouse to switch from ont to another layer.
The inverse tranformation (from tracked route to airwire) is not done with the DELETE tool. This action removes the connection. While forward and backward annotation is enable, deleting a connection is not possible from the board editor; it must be done in the schematic editor. To unroute a track, use the RIPUP tool:

Ripup

It is usefull to remember that selecting an airwire with RIPUP converts all adjacent routed wires and vias into airwires, up to the next pad, smd or airwire. Thus, by left-clicking twice on a track it quickly unroutes the connection. Tracks and vias can be moved with the MOVE command. Selecting a wire segment near an end point will move the end point of the track. Selecting the wire in the middle will move it in parallel. Note that to move components there origins have to be displayed (layer 23 (tOrigins) and 24 (bOrigins) for components respectively on top and bottom layers).
With the SPLIT command you add a bend in a wire. It is usefull to push or modify an existing track:

Split

Route the board according to the following illustration (track width is 50 mils):

Routed

Modifying the board

The CHANGE tool allows you to change any property of your design. When selecting the CHANGE tool, a contextual menu appears with the list of properties:

Change

Select WIDTH > 10 and click on any track of your design. The track width is modified. You can reverse the action with the UNDO command (Ctrl-Z). Note that modifying component names or values can’t be done with the CHANGE tool, it must necessary be done with the NAME and VALUE commands as in the schematic editor. Set the value of resistor R3 from 680 to 470 and check in the schematic that the value has been back annotated:

BackAnnotate

Perform the inverse action from the schematic editor and check that the board has been updated. Note that when you apply and action to an object that is too close from another, the software is enable to guess which is concern. In this situation, a single object is highlighted and a right-click allows to switch to the another potentially concerned object. Left-click finally applies the action to the current highlighted object.

Design rule check

Before manufacturing the PCB, it is safe to check the design thanks to the DRC (Design Rule Check). First click on the DRC icon.

DRC

The DRC configuration window appears. The designer can specify its own project design rules. Once the rules are configured, click the CHECK button to start the Design Rule Check. When there is no error, a message is simply display at the bottom of the board editor. If existing errors are found, a window appears:

DRC_Errors

Here two errors are detected. The hole size of the vias is too small according to the design rules. By selecting one of the error, the problem is highlighted in the design:

Error_Hilighted

With the CHANGE command, change the drill diameter of the vias from 23.62205 to 27.55906. Check again your design, you should, at the bottom-left corner of the window, have the message : “DRC: No errors”. Your design is ready for manufacturing.

Click here to return to the main summary

Introduction to EAGLE – Adding mounting holes to a PCB

This article is part of a tutorial dedicated to EAGLE. The reader may consult the other parts of the tutorial by following this link: Introduction to EAGLE

VIA versus HOLE

There is two ways (via or hole) to add a mounting hole in a PCB and the difference between the VIA and the HOLE tools can be confusing.
via hole
A via is composed of a hole and a copper area surounding the hole. But the main différence between vias and holes is the electric connection made between layers by the via. The HOLE tool just place a hole in the design without copper or connection. Depending on what the mounting hole is made for, you may add a VIA or a HOLE. The following capture shows the difference between vias and holes. On the left side of the PCB, holes has been added, and on the right side of the board, two vias has been placed.

Board

As it is illustrated on the following figure, vias are isolated from copper pour:

BoardCopperPour

Hole diameters

Regardless the selected tool, the hole diameter has to be defined. The PCB editor is generaly configured in mils (or inchs) and the fastening specification is generaly provided in millimeters. The following table is a quick references of most used diameters.
[MIL] [MM]
19.68504 mils 0.5 mm
23.62205 mils 0.6 mm
27.55906 mils 0.7 mm
31.49606 mils 0.8 mm
35.43307 mils 0.9 mm
39.37008 mils 1.0 mm
43.30709 mils 1.1 mm
47.24409 mils 1.2 mm
51.1811 mils 1.3 mm
55.11811 mils 1.4 mm
59.05512 mils 1.5 mm
62.99213 mils 1.6 mm
78.74016 mils 2.0 mm
86.61417 mils 2.2 mm
110.23622 mils 2.8 mm
125.98425 mils 3.2 mm

If the value is not listed, check this link : Distance converter.

Click here to return to the main summary

Introduction to EAGLE – Adding copper pour

This article is part of a tutorial dedicated to EAGLE. The reader may consult the other parts of the tutorial by following this link: Introduction to EAGLE

Copper pour

The copper pour outline is drawn with the POLYGON command:

Polygon

Select the POLYGON tool. If the copper pour needs to be attached to a net, you can enter the net name straight after selecting the tool and validate with the Enter key:

AttachNet

It is still possible to modify the connection by right clicking on the edge of the polygon, in the contextual menu, select NAME. In the pop-up window, replace GND by the label of the new connection. This is also useful to check that the connection has been successfully done.
Left-click to draw polygon edges and double click to close the polygon. Once the outline is drawn, it appears in dotted lines:

DottedLine

Click the RATSNETS to calculate the copper pour:

Ratsnets

The board should be updated. When the board is modified, the copper pour is not always recalculated. It is usefull to remember that RATSNETS force the calculation of the copper pour.

CopperPour

Board outline conflict

According to your design check rules, the copper pour may sometime not reach the board outline:

CopperPourOutline

This can be solved by setting the distance between the copper pour and the dimension layer equal to zero. Click on DRC, select tab Distance and set the distance equal to 0:

DistanceCopperPour

Attaching a net

Before attaching a net to the copper pour, it is sometime usefull to unroute the existing tracks already routed. Use the command RIPUP, for example “RIPUP GND”, to unroute all the tracks named GND.
To add or change the copper pour net attachment, select the NAME command and click on the polygon. A window pop up and the user can modify or specify the name of the copper pour. When the name is the same as an existing track (for example GND), an electric connection is automaticaly created between the track and the copper pour. On the following board, the copper pour is connected to the groung:

CopperPour

Remove copper pour

To definitively delete the copper pour, since the polygon is attached to the copper pour, delete the polygon. To temporary remove or hide the copper pour, select the RIPUP tool and click on the polygon. It removes the copper pour while keeping the polygon (dotted lines). Click RATSNETS again to recalculate the copper pour.

Introduction to EAGLE – Understanding layers

This article is part of a tutorial dedicated to EAGLE. The reader may consult the other parts of the tutorial by following this link: Introduction to EAGLE
Each layer in EAGLE is dedicated to a given function. Placing each item in the appropritaed layer is highly recommanded. This article presents each layer and describes it functionality. The famous Arduino MEGA 2560 board is taken as example. Note that the picture is not exactly identical to the PCB, but is quite enough to understand each layer:
ArduinoMega2650Front All

Layer 1 – Top

The first layer contains the top side tracks and the top side copper pour (if used).

Layer_1

Layer 2 to 15 – Route

This is the inner layer tracks (only for multilayer PCB).

Layer 16 – Bottom

This layer contains the bottom side tracks and the bottom side copper pour (if used).

Layer_16

Layer 17 – Pads

This layer contains the through-hole pads.

Layer_17

Layer 18 – Vias

This layer contains the through-hole vias.

Layer_18

Layer 19 – Unrouted

This layer contains the unrouted tracks, i.e. the airwires (rubberbands). Here almost all the board is routed, there is just a few unrouted tracks:

Layer_19

Layer 20 – Dimension

This layer contains the board outlines and circle for holes.

Layer_20

Layer 21 – tPlace

This layer contains the top side silk screen. It usualy contains the component outlines. Care must be taken not to cover any ares that have to be soldered. It is also possible to create additional and rather better­looking silk screen for documentation purposes in layer 51, tDocu. This may indeed cover soldered areas, since it is not output along with the manufacturing data.

Layer_21

Layer 22 – bPlace

This layer contains the bottom side silk screen (see layer 21 for more details).

Layer 23 – tOrigins

This layer contains the top side component origins. It contains the origin cross for each component. Top side components can be moved or modifyed only if this layer is visible.

Layer_23

Layer 24 – bOrigins

This layer contains the bottom side component origins (see layer 22 for more details). Bottom side components can be moves only if this layer is visible.

Layer 25 – tNames

This layer contains the top side service print. It usualy contains the component names and may appear on the PCB as the silk screen.

Layer_25

Layer 26 – bNames

This layer contains the bottom side service print (see layer 25 for more details).

Layer 27 – tValues

This layer contains the top side component value. It usualy contains the component value and appears on the PCB as the silk screen and service print.

Layer_27

Layer 28 – bValues

This layer contains the bottom side component value (see layer 27 for more details).

Layer 29 – tStop

This layer contains the top side solder stop mask (solder mask). This is the nogo area for the green laque. Data is implicitly created for THT and SMD pads, and optionally VIAs (depending on settings).

Layer_29

Layer 30 – bStop

This layer contains the bottom side solder stop mask (see layer 29 for more details).

Layer 31 – tCream

This layer contains the top side solder paste data for SMD, normally used to make stencils for printing the paste to the board before assembly. Data is implicitly created with SMD pads. This area should be a little smaller that the solder stop mask because the green laque shouldn’t overlap solder areas.

Layer_31

Layer 32 – bCream

This layer contains the bottom side solder cream (see layer 31 for more details).

Layer 33 – tFinish

This layer is dedicate to special finishing process (plated gold, silver carbon. It may also be used if some of the pads need immersion gold plating. It is not automaticaly generated and it must be drawn by designer.

Layer 34 – bFinish

This layer contains the bottom side finish data (see layer 33 for more details).

Layer 35 – tGlue

This layer contains the top side glue mask. For wave soldering of SMD parts, they must be glued to the board first. Usually, one small dot in the center of chips, and several dots under IC packages are used. This layer must be drawn by the designer, normally when designing the libraries.

Layer_35

Layer 36 – bGlue

This layer contains the bottom side glue mask (see layer 35 for more details).

Layer 37 – tTest

This layer is the top side test and adjustment. It is dedicated to testpoint for ICT (In Circuit Test).

Layer 38 – bTest

This layer is the bottom side test and adjustment. It is dedicated to testpoint for ICT (In Circuit Test).

Layer 39 – tKeepout

This layer is the top side keepout area for components. Components should not be placed in this area (except for part ower of the area).

Layer_39

Layer 40 – bKeepout

This layer is the bottom side keepout area for components (see layer 39 for more details).

Layer 41 – tRestrict

This layer is the top side keepout area for tracks. Tracks should not be placed in this area.

Layer 42 – bRestrict

This layer is the bottom side keepout area for tracks (see layer 41 for more details).

Layer 43 – vRestrict

This layer is the keepout area for vias.

Layer 44 – Drills

This layer contains the conducting through holes. It is usually used for pads (of through hole components) and vias.

Layer_44

Layer 45 – Holes

This layer contains the non-conducting holes. It is usually used for s used for mounting holes.

Layer_45

Layer 46 – Milling

This layer is dedicated to milling. If the board manufacturer has to mill oblong holes, you have to draw the milling contour of oblong holes in this layer. Any other inner cut­outs in the board are drawn in the same way. Draw the milling contours in this layer. Note that the board outline is not concerned and must be designed in the layer 20 (Dimension).

Layer 47 – Measures

This layer contains the measurement. It is not used during the manufacturing process, it is just display for information.

Layer_47

Layer 48 – Document

This layer contains the general documentation. Had here comments, or any usefull information that help understanding the design of the PDB.

Layer_48

Layer 49 – Reference

This layer contains the reference marks and is typicaly used for placing the fiducial marks. Fiducials are little target registration marks that are printed on PCBs, they are placed on the top copper layer (and bottom if you’re doing 2-layers) and allow the vision system of the pick and place to recognize where the PCB is at. They are not placed on the mask or silk because they are not as precisely aligned to the parts as the copper itself.

Layer_49

Here is a picture from Lady Ada (Adafruit company) that illustrate the automatic localization process of the fiducial marks:

4mmoffset

Layer 51 – tDocu

This layer contains the top side part documentation. Place additional graphical information for the documentation here. This layer is not used to print onto the board itself, but is a supplement to the graphical presentation which might be used for printed documentation. Care must be taken in layer 21, tPlace, not to cover any areas that are to be soldered. A more realistic appearance can be given, however, in the tDocu layer, which is not subject to this limitation.

Layer_51

Layer 52 – bDocu

This layer contains the bottom side part documentation (see layer 51 for more details).

DIY Lithium Battery Charger Shield for Arduino

$
0
0

DIY Lithium Battery Charger Shield for Arduino

6 Comments
intrologo-lithium-battery-charger

In this project, we are building a programmable single/multi cell lithium battery charger shield for Arduino. The shield provides LCD and button interface which let the user set the battery cut-off voltage from 2V to 10V and charge current from 50mA to 1.1A. The charger also provides the ability to monitor the battery status before and during charge.

The charger is based on LT1510 Constant Current/Constant Voltage Battery charger IC and controlled by Arduino UNO. The display on the shield is Nokia 5110 LCD which is very simple to use and still available on the market. There are two different battery connectors available on the shield, a two contact screw terminal block and a right angle 2mm JST-PH connector.

Circuit Design

The schematic of the project is drawn in SoloCapture, the schematic editor of SoloPCB tools. SoloCapture makes the schematic drawing process very easy and fast. You can download SoloPCB tools at Fabstream.com for FREE.

You can download the SoloPCB design files of the project by using the link below.

Please check out this video to see how to import the project libraries, open and synchronize the schematic and PCB files.

schematic-620-lithium-battery-charger

The lithium battery charger circuit is designed as an Arduino Shield. But the battery charger IC on the board can also work without MCU control. R3 and R4 sets the charge cut-off voltage, R2 ,R24 and C5 adjusts the charge current limit. With those passive component configurations, LT1510 can charge the battery and know when to stop. But we want to build a user programmable charger. So we had to take control of these functions. Anyway, when no code is present on Arduino, the charger has default cut-off voltage of 4.2V and maximum charge current of 1.1A.

component-side-lithium-battery-charger

Pulling VC pin of LT1510 to ground stops charging immediately. The pin 5 of Arduino assigned to drive Q2 Mosfet to stop charging when required. The battery voltage is divided by ten over R7 and R8 resistors and read by the A1 analog input. By using these two features, we can read the battery voltage and stop charging when the battery reaches a pre-determined voltage level.

In LT1510 datasheet, in addition to fixed resistor configuration, controlling the charge current by PWM method is also explained. Pin 6 of Arduino has PWM function and it is used for this purpose. Adjusting the PWM duty cycle easily adjusts the charge current. The current flowing to the battery is sensed by ACS712-5A Hall Effect current sensor IC and the sensor output is read by A0 analog input of Arduino. ACS712-5A outputs 0.185mV per 1A in addition to 2.5V. For example when the battery draws 1A, the sensor outputs 2.685V. To read the current more accurately, the internal voltage reference 1.1V is used so 10 bit ADC reading will fit between 0V and 1.1V at 1024 step resolution.

The maximum sensor output difference will be 1.1A x 0.185V = 0.204V resulting an output of 2.704V. By using the LM258 op-amp, we subtracted 2.5V from the sensor output and multiply the result by 5. This maps the sensor output from 0V (@0A) to 1.02 (@1.1A) which fits nicely between the ADC limits of 0V and 1.1V. There is still 0.1V margin left which is meaningful when considering the op-amp offset voltage and current sensor noise and offset.

5110 LCD display uses SPI interface and requires 3.3V power supply. Since the Arduino I/O pins works at 5V, to protect the LCD module, it is recommendedto connect 10K or 1K resistors in series to the signal lines. The LCD module includes backlight LEDs. Those LEDs are driven by Pin 8 over 330R current limiting resistor.

There are four buttons (up, down, left, right) connected to Pin A2-A5 of Arduino. Those pins are set as inputs and the internal pull up resistors are activated. So simply pulling the pins to ground by using the buttons is enough to detect the button activity.

There are two SMD LEDs on the board reserved for any kind of indication. They are connected to Pin 3 and Pin 4. Those pins are set as outputs. Depending on the LED characteristics, current limiting resistors should be connected in series with the LEDs.

PCB Design

The PCB of the project is designed in SoloPCB. SoloPCB is a pack of powerful tools consisting of schematic capture, PCB layout, and integrated autorouting. You can download SoloPCB tools at Fabstream.com for FREE and start using immediately.

You can download the SoloPCB design files of the project by using the link below.

Please check out this video to see how to import the project libraries, open and synchronize the schematic and PCB files.

PCB-lithium-battery-charger

Since this is an Arduino shield, it should have similar dimensions with Arduino UNO. The expansion headers must be properly positioned. The LCD, buttons, LEDs and the battery connectors are placed on the top layer to make the interface usable. All the other components are placed on the bottom layer.

buttons-and-connectors-lithium-battery-charger

LT1510 requires PCB area which is connected to the GND pins to cool down the IC during operation. And there is a recommended PCB layout in its datasheet which maximizes the noise reduction performance.

Part List

parts-lithium-battery-charger

The Bill of Materials of the Lithium Battery Charger shield is given below.

Quantity Part Description Designator
1 LT1510 Constant Current/Constant Voltage Battery Charger SO-16 U1
1 REF03 2.5V Voltage Reference SO8 U2
1 ACS712-5A Hall Effect Based Current Sensor 8-SOIC U3
1 LM258 Low Noise Operational Amplifier SO-8 U4
1 5110 LCD Module LCD1
2 SS14 1A 40V Schottky Rectifier SMA D1 D2
1 1N4148 General Purpose Diode SOD80C D5
3 BSS138 Mosfet SOT-23 Q1 Q2 Q3
1 Red LED 0805 D3
1 Green LED 0805 D4
1 220nF 50V 0805 X7R SMD Ceramic Capacitor C1
5 100nF 50V 0805 X7R SMD Ceramic Capacitor C4 C8 C9 C10 C11
2 1nF 50V 0805 X7R SMD Ceramic Capacitor C6 C7
1 10uF 25V 1206 X7R SMD Ceramic Capacitor C3
1 1uF 25V 1206 X7R SMD Ceramic Capacitor C5
1 22uF 16V Tantalum Capacitor B-Case C2
1 MSS1260-333 330uH Coilcraft Power Inductor L1
3 100R 1% 0805 Resistor R5 R6 R23
3 20K 1% 0805 Resistor R7 R19 R22
2 1K 1% 0805 Resistor R1 R10
1 70.6K 1% 0805 Resistor R4
6 10K 1% 0805 Resistor R11 R12 R13 R14 R20 R21
2 0805 Resistor Value Depends on the LEDs R15 R16
1 3K8 1% 0805 Resistor R24
3 100K 1% 0805 Resistor R3 R17 R18
1 330R 1% 0805 Resistor R9
1 300R 1% 0805 Resistor R2
1 180K 1% 0805 Resistor R8
4 Tact Push Button SMD SW1 SW2 SW3 SW4
1 1×6 2.54mm pitch 15mm height Male Header J2
2 1×8 2.54mm pitch 15mm height Male Header J3 J4
1 1×10 2.54mm pitch 15mm height Male Header J1
1 JST-PH Connector 2 Pin Right Angle J5
1 1×2 5.2mm Pitch Screw Terminal Block J6

Software

Page based design is applied in the project. There are four pages that lets the user enter the charge parameters and monitor the battery status. Adafruit PCD8544 and GFX libraries are used to drive Nokia 5110 LCD.

The first page is the Set Parameters page. On this page the user can enter the battery cut-off voltage and the maximum charge current, go to battery status page, and start charging. Up and down buttons are used to travel between the options and right and left buttons are used to change values or select any option.

set-parameters-page-lithium-battery-charger

The second page is the Battery Status Page. While not charging, the user can enter this page from the Set Parameters page and see the current battery voltage. Pressing the left or the light button make the charger return to the Set Parameters page.

battery-status-page-lithium-battery-charger

The third page shows the charging state of the battery. It shows the voltage and current status of the battery during charge. When right or left button is pressed, the charger stops charging and returns to the Set Parameters page.

charging-page-lithium-battery-charger

When the battery voltage reaches to the set voltage, the charger stops charging and displays the Charge Complete page.To exit, pressing the left or the right button is required.

charge-complete-page-lithium-battery-charger

The charger keeps the last used parameters in the internal EEPROM. When charging process starts, the parameters are saved. At startup the charger reads the values from the EEPROM so the user don’t have to enter the values each time.

To read the battery voltage and the charge current, A0 and A1 pins are used as analog inputs. The details of the ADC steps are explained in the code. To change the charge current, PWM function is used via pin 6. Adjusting the duty cycle changes the charge current. A lookup table including the current vs. duty cycle is constructed manually and used. Since we can read the current, it is also possible to change the duty cycle dynamically.

At startup, the charger displays a bitmap logo. It was a bit challenging to display this bitmap so we wanted to explain the process for 5110 LCD users who want to use this feature.

How to Create and Use Bitmap Images on 5110 LCD

This example is prepared to be used with Adafruit PCD8544 and GFX Arduino libraries.

First of all, we need to create the image that will be displayed on the 5110 LCD. There are lots of graphics editors that can be used for this purpose but we will use the most basic one, MS Paint.

  1. Start paint and create a new file.
  2. Select “Resize” on the tool ribbon.
  3. Choose “Pixels” and uncheck “Maintain aspect ratio”
  4.  We will create a full screen logo so enter the dimensions horizontal: 88 and vertical: 48. Actually the width of the screen is 84px but we experienced that the width should be a multiple of 8. The excess four bits in each line won’t be displayed.
  5. Save the image in “Monochrome Bitmap” type.

Now the blank image is ready for the design. The last four vertical columns on the image will be lost so don’t include them. You can see the image created for the charger project below.

logo-page-lithium-battery-charger

To display this image on the LCD, we need to convert it to a bit matrix. LCD Assistant is a useful tool which will help us at this point.

  1. Open LCD Assistant and select “Load Image” from the ”File” menu.
  2. Choose the image you created.
  3. On the settings tab, choose “Horizontal” as byte orientation. The size of the picture will be automatically detected.
  4. Leave the other fields as they are.
  5. From the “File” menu, choose “Save Output” and type the file name such as Logo.txt.
  6. Open the .txt file and replace “const unsigned char” with “static const unsigned char PROGMEM”

The image bit matrix is ready to use in the Arduino sketch. Paste it before the “void Setup()” section. To display image on the screen, you can use the following code;

display.clearDisplay();

display.drawBitmap(0, 0,  logo, 84, 48, 1);

display.display();

Arduino Code


SIM900 GPRS/GSM Shield

$
0
0

SIM900 GPRS/GSM Shield

Introduction

The SIM900 GSM/GPRS Shield provides you a way to use the GSM cell phone network to receive data from a remote location. The shield allows you to achieve this via any of the three methods:

  • Short Message Service
  • Audio
  • GPRS Service

The GPRS Shield is compatible with all boards which have the same form factor (and pinout) as a standard Arduino Board. The GPRS Shield is configured and controlled via its UART using simple AT commands. Based on the SIM900 module from SIMCOM, the GPRS Shield is like a cell phone. Besides the communications features, the GPRS Shield has 12 GPIOs, 2 PWMs and an ADC.

N95DG WITHOUT PACKAGED FRONT2.jpg

N95DG WITHOUT PACKAGED BACK.jpg

Features

  • Based on SIMCom‘s SIM900 Module
  • Quad-Band 850 / 900/ 1800 / 1900 MHz – would work on GSM networks in all countries across the world.
  • Control via AT commands – Standard Commands: GSM 07.07 & 07.05 | Enhanced Commands: SIMCOM AT Commands.
  • Short Message Service – so that you can send small amounts of data over the network (ASCII or raw hexadecimal).
  • Embedded TCP/UDP stack – allows you to upload data to a web server.
  • Speaker and Headphone jacks – so that you can send DTMF signals or play recording like an answering machine.
  • SIM Card holder and GSM Antenna – present onboard.
  • 12 GPIOs, 2 PWMs and an ADC (all 2.8 volt logic) – to augment your Arduino.
  • Low power consumption – 1.5mA(sleep mode)
  • Industrial Temperature Range – -40°C to +85 °C

Application Ideas

  • M2M (Machine 2 Machine) Applicatoions – To transfer control data using SMS or GPRS between two machines located at two different factories.
  • Remote control of appliances – Send SMS while you are at your office to turn on or off your washing machine at home.
  • Remote Weather station or a Wireless Sensor Network : Create a sensor node capable of transferring sensor data (like from a weather station – temperature, humidity etc.) to a web server (like pachube.com).
  • Interactive Voice Response System – Couple the GPRS Shield with an MP3 Decoder and DTMF Decoder (besides an Arduino) to create an Interactive Vocice Response System (IVRS).
  • Vehicle Tracking System – Couple the GPRS Shield with an Arduino and GPS module and install it in your car and publish your location live on the internet. Can be used as a automotive burglar alarm.

Cautions

  • Make sure your SIM card is unlocked.
  • The product is provided as is without an insulating enclosure. Please observe ESD precautions specially in dry (low humidity) weather.
  • The factory default setting for the GPRS Shield UART is 19200 bps 8-N-1. (Can be changed using AT commands).

Specifications

Item Min Typical Max Unit
Voltage 4.8 5.0 5.2 VDC
Current / 50 450 mA
Dimension(with antenna) 110x58x19 mm
Net Weight 76±2 g

Interface Function

Power select – select the power supply for GPRS shield(external power or 5v of arduino)
Power jack – connected to external 4.8~5VDC power supply
Antenna interface – connected to external antenna
Serial port select – select either software serial port or hareware serial port to be connected to GPRS Shield
Hardware Serial – D0/D1 of Arduino/Seeeduino
Software serial – D7/D8 of Arduino/Seeeduino only
Status LED – tell whether the power of SIM900 is on
Net light – tell the status about SIM900 linking to the net
UART of SIM900 – UART pins breakout of SIM900
Microphone – to answer the phone call
Speaker – to answer the phone call
GPIO,PWM and ADC of SIM900 – GPIO,PWM and ADC pins breakout of SIM900
Power key – power up and down for SIM900

Pins usage on Arduino

D0 – Unused if you select software serial port to communicate with GPRS Shield
D1 – Unused if you select software serial port to communicate with GPRS Shield
D2 – Unused
D3 – Unused
D4 – Unused
D5 – Unused
D6 – Unused
D7 – Used if you select software serial port to communicate with GPRS Shield
D8 – Used if you select software serial port to communicate with GPRS Shield
D9 – Used for software control the power up or down of the SIM900
D10 – Unused
D11 – Unused
D12 – Unused
D13 – Unused
D14(A0) – Unused
D15(A1) – Unused
D16(A2) – Unused
D17(A3) – Unused
D18(A4) – Unused
D19(A5) – Unused
Note: A4 and A5 are connected to the I2C pins on the SIM900. The SIM900 however cannot be accessed via the I2C .

A Simple Source Code Example

The demo code below is for the Arduino to send SMS message/dial a voice call/submit a http request to a website and upload datas to the pachube. It has been tested on Arduino Duemilanove but will work on any compatible variant, plesse note that this sketch uses the sorfware UART of ATmega328P. please follow the following steps for running this sketch.

  • With the GPRS Shield removed, download this sketch into your Arduino.
  • Disconnect the Xduino from USB port to remove power source.
  • Set the Serial Port jumpers on the GPRS Shield in SWserial position, to use the Soft Serial port of Arduino.
  • Connect the antenna to the GPRS Shield and insert the SIM Card.
  • Mount the GPRS Shield on Arduino.
  • Connect the Arduino to the computer by USB, and fire up your favorite serial terminal software on computer, choose the COM port for Arduino, set it to operate at 19200 8-N-1.
  • Type command in the terminal to execute different function, threr are 4 functions in the demo:
    • If you input ‘t’, the demo will send a SMS message to another cellphone which you set(you need set the number in the code);
    • If you input ‘d’, the program will dial a call to the other cellphone that you set(it is also need you set in the code );
    • If you input ‘h’, it will submit a http request to a web that you want to access(it need you set the web adress in the code), it will return a string from the website if it goes correctly;
    • If you input ‘s’, it will upload the datas to the pachube(for detail you can refer to the explanation in the code). I strongly recommend you input ‘h’ before input ‘s’, because uploading data to the pachube need do some setting, after execute the function of submit a http request, the setting will be set.
  • If the program returns error in the terminal after you typed the command, don’t worry, just try input the command again.

Note:

(1) The GPRS/GSM shield need external power supply to guarantee reliable operations.

(2) After attaching the shield to Arduino board and adding power supply, you need press the power button on the shield for about 2 seconds to turn on the shield.

/*Note: this code is a demo for how to using gprs shield to send sms message, dial a voice call and
  send a http request to the website, upload data to pachube.com by TCP connection,
 
  The microcontrollers Digital Pin 7 and hence allow unhindered
  communication with GPRS Shield using SoftSerial Library.
  IDE: Arduino 1.0 or later
  Replace the following items in the code:
  1.Phone number, don't forget add the country code
  2.Replace the Access Point Name
  3. Replace the Pachube API Key with your personal ones assigned
  to your account at cosm.com
  */
 
 
#include <SoftwareSerial.h>
#include <String.h>
 
SoftwareSerial mySerial(7, 8);
 
void setup()
{
  mySerial.begin(19200);               // the GPRS baud rate   
  Serial.begin(19200);    // the GPRS baud rate 
  delay(500);
}
 
void loop()
{
  //after start up the program, you can using terminal to connect the serial of gprs shield,
  //if you input 't' in the terminal, the program will execute SendTextMessage(), it will show how to send a sms message,
  //if input 'd' in the terminal, it will execute DialVoiceCall(), etc.
 
  if (Serial.available())
    switch(Serial.read())
   {
     case 't':
       SendTextMessage();
       break;
     case 'd':
       DialVoiceCall();
       break;
     case 'h':
       SubmitHttpRequest();
       break;
     case 's':
       Send2Pachube();
       break;
   }
  if (mySerial.available())
    Serial.write(mySerial.read());
}
 
///SendTextMessage()
///this function is to send a sms message
void SendTextMessage()
{
  mySerial.print("AT+CMGF=1\r");    //Because we want to send the SMS in text mode
  delay(100);
  mySerial.println("AT + CMGS = \"+86138xxxxx615\"");//send sms message, be careful need to add a country code before the cellphone number
  delay(100);
  mySerial.println("A test message!");//the content of the message
  delay(100);
  mySerial.println((char)26);//the ASCII code of the ctrl+z is 26
  delay(100);
  mySerial.println();
}
 
///DialVoiceCall
///this function is to dial a voice call
void DialVoiceCall()
{
  mySerial.println("ATD + +86138xxxxx615;");//dial the number
  delay(100);
  mySerial.println();
}
 
///SubmitHttpRequest()
///this function is submit a http request
///attention:the time of delay is very important, it must be set enough 
void SubmitHttpRequest()
{
  mySerial.println("AT+CSQ");
  delay(100);
 
  ShowSerialData();// this code is to show the data from gprs shield, in order to easily see the process of how the gprs shield submit a http request, and the following is for this purpose too.
 
  mySerial.println("AT+CGATT?");
  delay(100);
 
  ShowSerialData();
 
  mySerial.println("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"");//setting the SAPBR, the connection type is using gprs
  delay(1000);
 
  ShowSerialData();
 
  mySerial.println("AT+SAPBR=3,1,\"APN\",\"CMNET\"");//setting the APN, the second need you fill in your local apn server
  delay(4000);
 
  ShowSerialData();
 
  mySerial.println("AT+SAPBR=1,1");//setting the SAPBR, for detail you can refer to the AT command mamual
  delay(2000);
 
  ShowSerialData();
 
  mySerial.println("AT+HTTPINIT"); //init the HTTP request
 
  delay(2000);
  ShowSerialData();
 
  mySerial.println("AT+HTTPPARA=\"URL\",\"www.google.com.hk\"");// setting the httppara, the second parameter is the website you want to access
  delay(1000);
 
  ShowSerialData();
 
  mySerial.println("AT+HTTPACTION=0");//submit the request 
  delay(10000);//the delay is very important, the delay time is base on the return from the website, if the return datas are very large, the time required longer.
  //while(!mySerial.available());
 
  ShowSerialData();
 
  mySerial.println("AT+HTTPREAD");// read the data from the website you access
  delay(300);
 
  ShowSerialData();
 
  mySerial.println("");
  delay(100);
}
 
///send2Pachube()///
///this function is to send the sensor data to the pachube, you can see the new value in the pachube after execute this function///
void Send2Pachube()
{
  mySerial.println("AT+CGATT?");
  delay(1000);
 
  ShowSerialData();
 
  mySerial.println("AT+CSTT=\"CMNET\"");//start task and setting the APN,
  delay(1000);
 
  ShowSerialData();
 
  mySerial.println("AT+CIICR");//bring up wireless connection
  delay(3000);
 
  ShowSerialData();
 
  mySerial.println("AT+CIFSR");//get local IP adress
  delay(2000);
 
  ShowSerialData();
 
  mySerial.println("AT+CIPSPRT=0");
  delay(3000);
 
  ShowSerialData();
 
  mySerial.println("AT+CIPSTART=\"tcp\",\"api.cosm.com\",\"8081\"");//start up the connection
  delay(2000);
 
  ShowSerialData();
 
  mySerial.println("AT+CIPSEND");//begin send data to remote server
  delay(4000);
  ShowSerialData();
  String humidity = "1031";//these 4 line code are imitate the real sensor data, because the demo did't add other sensor, so using 4 string variable to replace.
  String moisture = "1242";//you can replace these four variable to the real sensor data in your project
  String temperature = "30";//
  String barometer = "60.56";//
  mySerial.print("{\"method\": \"put\",\"resource\": \"/feeds/42742/\",\"params\"");//here is the feed you apply from pachube
  delay(500);
  ShowSerialData();
  mySerial.print(": {},\"headers\": {\"X-PachubeApiKey\":");//in here, you should replace your pachubeapikey
  delay(500);
  ShowSerialData();
  mySerial.print(" \"_cXwr5LE8qW4a296O-cDwOUvfddFer5pGmaRigPsiO0");//pachubeapikey
  delay(500);
  ShowSerialData();
  mySerial.print("jEB9OjK-W6vej56j9ItaSlIac-hgbQjxExuveD95yc8BttXc");//pachubeapikey
  delay(500);
  ShowSerialData();
  mySerial.print("Z7_seZqLVjeCOmNbEXUva45t6FL8AxOcuNSsQS\"},\"body\":");
  delay(500);
  ShowSerialData();
  mySerial.print(" {\"version\": \"1.0.0\",\"datastreams\": ");
  delay(500);
  ShowSerialData();
  mySerial.println("[{\"id\": \"01\",\"current_value\": \"" + barometer + "\"},");
  delay(500);
  ShowSerialData();
  mySerial.println("{\"id\": \"02\",\"current_value\": \"" + humidity + "\"},");
  delay(500);
  ShowSerialData();
  mySerial.println("{\"id\": \"03\",\"current_value\": \"" + moisture + "\"},");
  delay(500);
  ShowSerialData();
  mySerial.println("{\"id\": \"04\",\"current_value\": \"" + temperature + "\"}]},\"token\": \"lee\"}");
 
 
  delay(500);
  ShowSerialData();
 
  mySerial.println((char)26);//sending
  delay(5000);//waitting for reply, important! the time is base on the condition of internet 
  mySerial.println();
 
  ShowSerialData();
 
  mySerial.println("AT+CIPCLOSE");//close the connection
  delay(100);
  ShowSerialData();
}
 
void ShowSerialData()
{
  while(mySerial.available()!=0)
    Serial.write(mySerial.read());
}

AT Command Tester Application

AT Command Tester is a free online tool test AT Commands and other modem functionalities of 2G modules (GPRS/EDGE) , 3G Modules (HSDPA/EVDO) and 4G Modules (LTE).AT Command Tester tool connects to the modem port of the device and can test various modem functions such as getting device information, gprs data call, voice call,http access, checking signal condition, network registration, SMS functions, SIM access, phonebook functions etc.

In the ‘Port Configuration’ section of the tool, users can search for available ports using the ‘Find Ports’ button. Then using the ‘Connect’ button, users can connect to the modem port of the device.

In the ‘Command Mode’ tab of AT Command Tester, single AT commands can be sent. The drop down list provides AT command description and examples. Users can modify the default command settings.

M2m img1.PNG
Under the ‘Script Mode’ tab, multiple AT commands can be sent at a time. Users can add descriptive comments and save the script on their local machine.

Script mode.PNG

Data Call

To make a data call with the modem, you need to connect to the APN of the carrier network. The carrier APN and other required information are stored in the SIM card and are referred as PDP contexts. Typically multiple PDP contexts are stored in the SIM for different call types. With the AT Command Tester you can edit/add/delete PDP contexts in a easy to use user interface.

Datacall.PNG

Typical call setup sequence,

AT+CGDCONT?

+CGDCONT: 1,”IP”,”epc.tmobile.com”,”0.0.0.0″,0,0
+CGDCONT: 2,”IP”,”test5″,”0.0.0.0″,0,0
+CGDCONT: 3,”IP”,””,”0.0.0.0″,0,0

OK
Checking registration status…

AT+CREG?

+CREG: 0,1

OK
The device is registered in home network.

Checking if device is already connected…

AT+CGACT?

+CGACT: 1,0
+CGACT: 2,0
+CGACT: 3,0

OK
AT+CMEE=1

OK
Attaching to network…
AT+CGATT=1

OK

Connecting…

AT+CGACT=1, 1

OK
Connect Sucessful
SMS

The SMS tab of the ‘AT Command Tester’ tool provides the interfaces to send SMS messages. You can also list/view/delete SMS messages stored on the SIM.

Sms.PNG
General sequence for sending SMS message,

Checking registration status…

AT+CREG?

+CREG: 0,1

OK
The device is registered in home network.

AT+CMGS=”858XXXXXXX”

> Test Message with AT Command Tester�

+CMGS: 19

OK
SMS Send successful

Network Selection – This tab allows the user to manually select available networks. Modems are typically set for automatic network selection. ‘Find Networks’ button will command the modem to scan for available networks.

Network selection.PNG

AT+COPS command will initiate network scan in the modem,

Finding Networks. Please wait..

AT+COPS=?

+COPS: (2,”T-Mobile”,”T-Mobile”,”310260″),(1,”AT&T”,”AT&T”,”310410″),,(0,1,4),(0,1,2)

OK
Networks found

Phonebook

With the ‘Phone Book’ tab, you can add/delete/read phone book entries stored on the SIM,

Phone book.PNG

Getting phonebook entries..

AT+CPBR=1,99

+CPBR: 1,”*233″,129,”Refill Now”

+CPBR: 2,”#999#”,255,”Check Balance”

+CPBR: 3,”8878878878″,129,”Test”

OK

SIM900 HTTP

With the ‘HTTP’ tab, you can read the bearer profiles and test HTTP GET and HTTP POST,

Http.PNG

Getting Bearer profiles..

AT+SAPBR=4,1

+SAPBR:
CONTYPE: GPRS
APN:
PHONENUM:
USER:
PWD:
RATE: 2

OK
AT+SAPBR=4,2

+SAPBR:
CONTYPE: GPRS
APN:
PHONENUM:
USER:
PWD:
RATE: 2

OK
AT+SAPBR=4,3

+SAPBR:
CONTYPE: GPRS
APN:
PHONENUM:
USER:
PWD:
RATE: 2

OK
Checking registration status…

AT+CREG?

+CREG: 0,1

OK
The device is registered in home network.

Querying bearer 1 .

AT+SAPBR=2,1

+SAPBR: 1,1,”162.184.222.162″

OK
Bearer 1 is Connected.IP address is “162.184.222.162”

Bearer 1 is Connected.

Initializing HTTP service…

AT+HTTPINIT

OK
Error initializing HTTP service.

Setting up HTTP parameters..

AT+HTTPPARA=”URL”,”http://www.m2msupport.net/m2msupport/http_get_test.php

OK
AT+HTTPPARA=”CID”,1[[|]]

OK
AT+HTTPACTION=0

OK

HTTP GET is sucessful

AT+HTTPREAD

+HTTPREAD:58
Sucessful HTTP GET test. Data received from m2msupport.net
OK
Terminating HTTP session..

AT+HTTPTERM

OK

SIM900 FTP

FTP Get and Put with SIM900 module can be tested as shown below,

Ftp.PNG

Checking registration status…

AT+CREG?

+CREG: 0,1

OK
The device is registered in home network.

Querying bearer 1 .

AT+SAPBR=2,1

+SAPBR: 1,1,”162.184.222.162″

OK
Bearer 1 is Connected.IP address is “162.184.222.162”

Bearer 1 is Connected.

Setting up FTP parameters..

AT+FTPCID=1

OK
AT+FTPSERV=”ftp.m2msupport.net”

OK
AT+FTPUN=”xxxxxx”

OK
AT+FTPPW=”xxxxxxx”

OK
AT+FTPGETNAME=”ftptest.txt”

OK
AT+FTPGETPATH=”/www/m2msupport/”

OK
AT+FTPGET=1

OK
+FTPGET:1,1
FTP session sucessfully started

AT+FTPGET=2,1024

+FTPGET:2,784
2-11-16 10:53:34.769 ———————————————–
eclipse.buildId=M20120914-1800
java.version=1.6.0_16
java.vendor=Sun Microsystems Inc.
BootLoader constants: OS=win32, ARCH=x86, WS=win32, NL=en_US
Framework arguments: -product org.eclipse.epp.package.java.product
Command-line arguments: -os win32 -ws win32 -arch x86 -product org.eclipse.epp.package.java.product

!ENTRY org.eclipse.m2e.logback.appender 4 0 2012-11-16 12:11:54.493
!MESSAGE Unable to update index for central|http://repo.maven.apache.org/maven2: C:\Users\sgobi\.m2\repository\.cache\m2e\1.2.0\26522e0d83a422eed93329ece7565cfc\nexus-maven-repository-index.zip (The system cannot find the file specified)

!ENTRY org.eclipse.jdt.ui 4 10001 2012-11-16 13:21:21.138
!MESSAGE Internal Error
!STACK 1
OK
AT+FTPGET=2,1024

+FTPGET:2,0

OK
FTP data transfer is complete
+FTPGET:1,0
FTP session end

How to buy

Here to buy SIM900 GPRS/GSM Shield on store

FAQ

Resources


GPRS Camera Project

$
0
0

GPRS Camera Project

About:
In short, this was a project I started working on out of necessity when vandals damaged a family member’s summer cabin. The crux of the project is a webcam of decent resolution (in this case 640×480) which can be located in a region with no WiFi, no internet connection, and no electricity. There are existing products on the market which satisfy these requirements, but they tend to be specialized (ie most shops don’t stock them) and expensive.

And so was born this project, in which a cheap LinkSprite camera is paired with an inexpensive solar powered Arduino controller and a GPRS interface.

Parts List:

PHASE 1

The first step in this project is to confirm that the camera and the arduino board can interface properly, and pass the image file on to a processing program running on the PC through its serial port.

Arduino Code:

Note: In this code, the LinkSprite camera is connected to pins 4 (RX) and 5 (TX), and the libraries used are available here. It is a modification of the example code given at that website. I provide the rough code here not just because it is useful, but because during this phase of development I had literally dozens of engineers and techies claim that an Arduino was too weak to ever transmit photos to a computer.

#include "JPEGCamera.h"
#include "NewSoftSerial.h"

//Create an instance of the camera
JPEGCamera camera;

const int buttonPin = 7;
const int ledPin = 13;

//Count is used to store the number of characters in the response string.
unsigned int count=0;
//Size will be set to the size of the jpeg image.
int size=0;
//This will keep track of the data address being read from the camera
int address=0;
//eof is a flag for the sketch to determine when the end of a file is detected
//while reading the file data from the camera.
int eof=0;

void setup(){
  camera.begin();
  Serial.begin(19200);
  pinMode(ledPin,OUTPUT);
  
  //Reset the camera
  count=camera.reset(response);
  delay(3000);
  
   //Take a picture
   count=camera.takePicture(response);
    
   //Get the size of the picture
   count = camera.getSize(response, &size);

  while(address<size){            <span="">//Read the data starting at the current address.
        count=camera.readData(response, address);
        //Store all of the data that we read to the SD card
        for(int i=0; i<count; i++){=""             <span="">//Check the response for the eof indicator (0xFF, 0xD9). If we find it, set the eof flag
            if((response[i] == (char)0xD9) && (response[i-1]==(char)0xFF))eof=1;
            //Save the data to the SD card
            Serial.print(response[i]);
            digitalWrite(ledPin,HIGH);
            //If we found the eof character, get out of this loop and stop reading data
            if(eof==1)break;
        }
        //Increment the current address by the number of bytes we read
        address+=count;
        digitalWrite(ledPin,LOW);
        //Make sure we stop reading data if the eof flag is set.
        if(eof==1)break;
  }
  return;
}

void loop(){
}

Processing Code:

import processing.serial.*;
   
 Serial myPort;  
 OutputStream output;  
   
   
 void setup() {
   
  size(320, 240);
   
  //println( Serial.list() );
  myPort = new Serial( this, Serial.list()[5], 19200);
  myPort.clear();  
   
  output = createOutput("pic.jpg");
 }  
   
   
 void draw() {
   
  try {
   while ( myPort.available () > 0 ) {
    output.write(myPort.read());  
    print("*");
   }  
  }   
  catch (IOException e) {  
   e.printStackTrace();  
  }  
 }  
   
   
 void keyPressed() {
   
  try {
   output.flush(); // Writes the remaining data to the file
   output.close(); // Finishes the file
  }   
   
  catch (IOException e) {  
   e.printStackTrace();  
  }  
 }    

PHASE 2

The second step in this project is to confirm that the Arduino board can send e-mail messages through the GPRS cell phone network. This requires an activated SIM card, a valid cell phone service (some providers require a data plan, others will work with a basic voice & text plan), and of course a GPRS shield for the Arduino. I am using the Seedstudio version, but others that use the AT protocals should work with this code as well.

Arduino code:

Note: In the following code, the APN, username, and password are specific to each service provider. However these can usually be found with a quick online search. Also, in my own testing it appears that the sender e-mail address needs to be a valid address but no password is required for it. The sender e-mail isn’t really important for this project since the code sends an e-mail to the user directly, but is included as the e-mail protocols require it.  The recipient address is the destination for the final photos and data. It should also be noted that the delays are the values that worked for me, but may need to be adjusted to give the server sufficient time to respond to each command.

#include <SoftwareSerial.h>
#include <String.h>


SoftwareSerial mySerial(7, 8);
 
void setup()
{
  mySerial.begin(19200);               // the GPRS baud rate
  Serial.begin(19200);    // the GPRS baud rate
  delay(500);
}
 
void loop()
{
  if (Serial.available())
    switch(Serial.read())
   {
      case 'e':
       SendEmail();
       break;
   } 
  if (mySerial.available())
    Serial.write(mySerial.read());
}
 
///Send EMail

void SendEmail()
{

  mySerial.println("AT+CIPSHUT");
  delay(100);
  mySerial.println("AT+CSTT=\"APN\",\"username\",\"password\"\r");
  delay(2200);
  ShowSerialData();
  mySerial.println("AT+CIPSHUT");
  delay(200);
  mySerial.println("AT+CIPSTART=\"TCP\",\"gprs.provider.com\",25");
  delay(2500);
   ShowSerialData();
  mySerial.println("AT+CIPSEND");
  delay(400);
  mySerial.println("HELO gprs.provider.com");
  delay(400);
     ShowSerialData();
  mySerial.println((char)26);//the ASCII code of the ctrl+z is 26
  delay(400);
  mySerial.println("AT+CIPSEND");
  delay(400);
  mySerial.println("MAIL From: address@server.com");
  delay(400);
  mySerial.println((char)26);//the ASCII code of the ctrl+z is 26
  delay(400);
     ShowSerialData();
  mySerial.println("AT+CIPSEND");
  delay(200);
  mySerial.println("RCPT To: address@server.com");
  delay(400);
  mySerial.println((char)26);//the ASCII code of the ctrl+z is 26
  delay(400);
       ShowSerialData();
  mySerial.println("AT+CIPSEND");
  delay(300);
  mySerial.println("DATA");
  delay(400);
  mySerial.println((char)26);//the ASCII code of the ctrl+z is 26
  delay(400);
  ShowSerialData();
  mySerial.println("AT+CIPSEND");
  delay(200);
  mySerial.println("From: \"SENDER\"<address@server.com>");
  delay(200);
    mySerial.println((char)26);//the ASCII code of the ctrl+z is 26
  delay(400);
  ShowSerialData();
    mySerial.println("AT+CIPSEND");
  delay(200);
  mySerial.println("To: \"RECIPIENT\"<address@server.com>");
  delay(100);
    mySerial.println((char)26);//the ASCII code of the ctrl+z is 26
  delay(400);
  ShowSerialData();
    mySerial.println("AT+CIPSEND");
  delay(200);
  mySerial.println("Subject: EMail Test");
  delay(200);
  mySerial.println((char)26);//the ASCII code of the ctrl+z is 26
  delay(400);
  ShowSerialData();
    mySerial.println("AT+CIPSEND");
  delay(200);
  mySerial.println("This is a test of the cell phone email system");
  delay(200);
  ShowSerialData();
  mySerial.println((char)26);//the ASCII code of the ctrl+z is 26
  delay(400);
      mySerial.println("AT+CIPSEND");
  delay(200);
  mySerial.println(".");
  delay(600);
  ShowSerialData();
  mySerial.println((char)26);//the ASCII code of the ctrl+z is 26
  delay(400);
  mySerial.println("AT+CIPSHUT");
  delay(100);
}
 


void ShowSerialData()
{
  while(mySerial.available()!=0)
    Serial.write(mySerial.read());
}

3G + GPS shield over Arduino and Raspberry Pi

$
0
0

3G + GPS shield over Arduino and Raspberry Pi

Difficulty Level: Expert –

https://s7.addthis.com/static/tweet.html#href=https%3A%2F%2Fwww.cooking-hacks.com%2Fdocumentation%2Ftutorials%2F3g-gps-shield-arduino-raspberry-pi-tutorial%2F%23.Vn8VQGqJUWs.twitter&dr=https%3A%2F%2Fwww.cooking-hacks.com%2F3g-gprs-shield-for-arduino-3g-gps-audio-video-kit&conf=product%3Dtbx-300%26pubid%3Dra-550b04b6022f544d%26data_track_addressbar%3Dfalse&share=url_transforms%3Dshorten%253Dtwitter%25253Dbitly%2523%2540!defrag%253D1%2523%2540!remove%253D0%25253Dsms_ss%252523%252540!1%25253Dat_xt%252523%252540!2%25253Dat_pco%252523%252540!3%25253Dfb_ref%252523%252540!4%25253Dfb_source%23%40!shorteners%3Dbitly%253D%23%40!imp_url%3D1%23%40!url%3Dhttps%253A%252F%252Fwww.cooking-hacks.com%252Fdocumentation%252Ftutorials%252F3g-gps-shield-arduino-raspberry-pi-tutorial%252F%23%40!title%3D3G%2520%252B%2520GPS%2520shield%2520over%2520Arduino%2520and%2520Raspberry%2520Pi%23%40!smd%3Drsi%253D%2523%2540!rxi%253Dundefined%2523%2540!gen%253D0%2523%2540!rsc%253D%2523%2540!dr%253Dhttps%25253A%25252F%25252Fwww.cooking-hacks.com%25252F3g-gprs-shield-for-arduino-3g-gps-audio-video-kit%2523%2540!sta%253DAT-ra-550b04b6022f544d%25252F-%25252F-%25252F567f15402bc13f85%25252F1%23%40!passthrough%3D&tw=url%3Dhttps%253A%252F%252Fwww.cooking-hacks.com%252Fdocumentation%252Ftutorials%252F3g-gps-shield-arduino-raspberry-pi-tutorial%252F%2523.Vn8VQGqJUWs.twitter%23%40!counturl%3Dhttps%253A%252F%252Fwww.cooking-hacks.com%252Fdocumentation%252Ftutorials%252F3g-gps-shield-arduino-raspberry-pi-tutorial%252F%23%40!count%3Dhorizontal%23%40!text%3D%23%40!related%3D%23%40!hashtags%3D%23%40!width%3D110

The 3G shield for Arduino and Raspberry Pi enables the connectivity to high speed WCDMA and HSPA cellular networks in order to make possible the creation of the next level of worldwide interactivity projects inside the new “Internet of Things” era.

The module counts also with an internal GPS what enables the location of the device outdoors and indoors combining standard NMEA frames with mobile cell ID triangulation using both assisted-mobile (A-GPS) and mobile-based (S-GPS) modes.

Other interesting accessories which can be connected to the module are a 2MP high resolution camera (1600 x 1200) UXGA which enables take incredible photos and videos, an audio kit including microphone , speaker , hands free and headphones sets and a SD socket to save directly all the data coming from the 3G network or recorded from the video camera. You can even reproduce audio filesstored in the SD card (like a mp3 player!).

You can also use it as a standard 3G modem at full speed (~7.2Mbps download, ~5.5Mbps upload) just connecting it through its specific mini-USB socket to your laptop (Linux, Windows, MacOS).

The new communicating module is specially oriented to work with Internet servers implementing internally several application layer protocols which make easier to send the information to the cloud. We can make HTTP and HTTPS (secure mode) navigation, downloading and uploading content to a web server. In the same way FTP and FTPS (secure mode) protocols are also available which is really useful when your application requires handling files. You can even send and receive mails directly from Arduino using the SMTP and POP3 clients implemented internally.

With the SD Card socket so you can handle a complete FAT16 file systems and store up to 32GB of information. This specially useful as the 3G module can work at full speed (~7.2Mbps download, ~5.5Mbps upload) when working with the SD files directly without need of Arduino for data or files management.

The GPS module also makes possible perform geolocation services even in indoors as it can work in A-GPS and S-GPS modes, so the location given by the GPS through NMEA sentences is completed with the cell information provided by both the 3G module and external Internet Geoposition Servers which helps you to get the most accurate location in each case.

Features

  • WCDMA and HSPA 3G networks compatibility
  • Internal GPS for Assisted A-GPS and Supported S-GPS modes
  • High Resolution Camera (2MP) for photo and video recordings available
  • Audio Kit including microphone, speaker, hands free and headphones available
  • SD file system up to 32GB
  • Works as a standard 3G modem in Linux/Windows/MacOS (~7.2Mbps download, ~5.5Mbps upload)
  • Talk directly to web servers by HTTP/HTTPS (secure)
  • Upload and download files directly by FTP/FTPS (secure)
  • Send and receive mails by POP3/SMTP
  • Play compressed audio files

NOTE: The Arduino codes of the tutorial have developed to work on Arduino IDE v1.0.1

NOTE: All the code examples in this tutorial developed for Raspberry Pi use the arduPi library. You can see the documentation and download the library here.

Kits and Accessories

Kits

Accesories

NOTE: the accessories (antennas, camera, microphone, speakers, headset, SD) are not included in the basic package. They may be acquired in any of the multi kits or by separate.

NOTE: If you only need to send SMS or use a low bandwidth for data transfer you can use our cheaper GPRS/GSM Quadband SIM900 module for Arduino and Raspberry Pi.

Does make sense a 3G module for a low speed microcontroller device such as Arduino?

Definitively yes.

On the one hand you can use the Arduino UART at full speed ~ 115kbps, so the communication of data will be at the same bandwidth as if you had the Arduino connected directly to the USB directly (obviously with more initial latency). With the GPRS modules available in the market until now the speed limit was established by the GPRS network ~ 20kbps, so now we get 6 times more download performance than before. The upload speed the increment three times from 10kbps (GPRS) to 35kbps (3G).

On the other hand there is a bunch of actions can be made directly from the 3G module without having to go through the Arduino microcontroller. This means you will control all the action from the main program running in Arduino although the data may flow from the 3G module to the SD card or from the video camera to the 3G module without going through the UART avoiding a possible bottle neck and ensuring maximum speed performance given by your 3G carrier (~7.2Mbps download, ~5.5Mbps upload at max). Some of this independent actions include:

  • Uploading and downloading files to HTTP and FTP servers directly from or to the SD
  • Recording and uploading video and photos to the Internet using the video camera connected directly to the module
  • Recording ambient audio and sending to a web server

This files may be also stored in the SD card of the 3G and in order to manage them after.

As well as this, the module offers theoretically also the possibility of performing Video-Calls. We say “theoretically” as the tests performed in Cooking Hacks we got a carrier error, the same we got when trying to make a Video-Call with our Smartphones so, although everything points it is is a carrier problem we can not ensure the Video-Call functionality (if you get please let us know!).

As pointed before the 3G module can also be used as and standalone 3G/GPRS USB modem! It works in Linux, Windows and MacOS, just plug it through its specific USB connector to your laptop and follow the steps located in the current manual.

You can control also the kind of network service and the quality of the signal received (RSSI) from the surrounding cells you are using even change among them: GSM – GPRS – WCDMA – HSPA depending on the coverage of the zone. Get detailed information about the frequency band you are using to connect to the carrier and the quality of the signal.

Article Index

1. FeaturesGo to index

Electrical features

The 3G module used is the SIM5218 from SIMCOM. The power supply of SIM5218 is from a single voltage source of VBAT= 3.4v-4.2v. In some case, the ripple in a transmit burst may cause voltage drops when current consumption rise to typical peaks of 2A. So the power supply must be able to provide sufficient current up to 2A. The maximum rating are VBAT=4,4v and 3A peak. The maximum value of voltage for digital or analogy pins is 2.8v.

Radio features

SIM5218 is a quad-band GSM/GPRS/EDGE and UMTS engine that works on frequencies of GSM 850MHz, EGSM 900 MHz, DCS 1800 MHz, PCS1900 MHz, and WCDMA 2100M/1900M/850M.

Output power:

  • UMTS 850/900/1900/2100: 0.25W
  • GSM850/GSM900: 2W
  • DCS1800/PCS1900: 1W

NOTE: when flight mode is activated RF functions are closed. The mode can be changed by putting the jumper in position (see 3G shield diagram below).

NOTE FOR US USERS: We have tested the new 3G shield with the AT&T network which supports nativelly the GSM and 3G protocolos. With other carriers may also work although we haven’t tried and thus we can not ensure it. For this reason we recommend to use AT&T SIM cards.

Extra features

  • USIM interface: support SIM cards: 3V & 1.8V
  • High speed USB interface for modem
  • Three audio channels include two microphones inputs and three audio outputs.
  • A camera interface is provided in FPC connector and 2mm pitch holes.
  • I2C interface is provided.
  • 8-bit ADC input with an input voltage range between 2.65v and GND
  • 2.8v LDO power output
  • 4 bit microSD card interface
  • 3 modes of GPS (stand alone, S-GPS y A-GPS)
  • FTP and FTPS for managing files
  • TCP and UDP sockets
  • POP3 and SMTP for e-mail

2. HardwareGo to index

3G Shield diagram

Version 2 of the shield:

NOTE: The Arduino/Raspberry Pi jumper MUST be in Arduino position. The Raspberry Pi position should be used only if the shield is connected to a Raspberry Pi. A wrong position of this jumper can damage the 3G shield

Version 1 of the shield:

3G Shield PCB

Version 2 of the shield:

Version 1 of the shield:

3. AntennasGo to index

Connections

SIM5218 has 3 UFL connectors. Two for diversity of 3G mobile carriers and one for GPS antenna. The impedance of the RF interface is 50Ω. It is recommended use just the “main” antenna socket for the mobile connection unless you experience coverage or performance problems. In this case two antennas allowing diversity may be placed.

Also, the module allows to solder the antenna to the pad, or attach it via contact springs.

Antenna availability

We recommend the usage of the following antennas:

4. BandwidthGo to index

3G module connected with Arduino allows downlinks rates over 115200 bauds (~11.5KBps), the maximum UART’s speed and uplinks rates over 30000 bauds (~3KBps). Using the module as 3G USB modem we got speeds of 2Mbps (~222KBps) for downlink and 0.7Mbps (~77KBps) for uplink and. The connection speed may vary depending on the state of the network, the quality of the signal and the carrier.

5. Using 3G module with AT commandsGo to index

Important issues:

  • Use capital letters for AT commands.
  • Send CR (Carriage return) and LF (Line feed) after the AT command.
  • Place the serial communication jumpers in the right position.
  • Use an external power supply and place the power jumpers in the right position. If the shield is powered from the Arduino or Raspberry Pi, the power jumper must be in Arduino 5V position. If the shield is powered from the Vin input (in the shield), the power jumper must be in Vext position.

Important type commands in capital letters and with CR (carriage return) and LF (line feed)!!!

Command Response Description
AT OK If you get OK, the communication with the module is working
AT+CPIN=”****” OK If the SIM card is locked with PIN (**** is the pin number)
AT+COPS? Operator information

NOTE: If your 3G module doesn’t answer to AT commands, maybe it is configured in a different baudrate. The command for change it temporally is AT+IPR. Try differents baudrates (300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800,921600, 3200000,3686400,4000000 ) until you get to communicate. Once you can communicate, you can configure it in the baudrate you want.

Using 3G module with AT commands in Arduino

The first thing we are going to do with the module is to connect the module to a PC directly (using an Arduino as gateway) and check the basic AT commands. In this case, serial communication jumpers have to be set on USB gateway position.

Remember take out the ATmega microcontroller from the Arduino gateway.

Basic configuration:

Connect the shield to the Arduino gateway.

Then connect the SIM card and the USB cable.

Finally plug the USB cable to the computer and open a serial port terminal to communicate via the usb port (e.g: hyperterminal (win), cutecom / gtkterm (linux)).

If you use the Arduino IDE serial monitor for sending AT commands – Be sure that you are sending CR (Carriage return) and LF (Line Feed).

Set the baudrate to 115200 bps and open the serial port, then press the ON button for two seconds. Then if you type AT you’ll get OK, this means that the communication with the module is working fine. Now, with the module working you can check some AT commands to control the module.

NOTE: With some sketches, the buffer of the UART may be small, to increase the length of the buffer you need to change these lines in the file HardwareSerial.h in /arduino-1.0.X/hardware/arduino/avr/cores/arduino/ (or in file HardwareSerial.cpp in /arduino-1.0.X/hardware/arduino/cores/arduino/ depending on the Arduino IDE version)

#if (RAMEND < 1000)
#define SERIAL_TX_BUFFER_SIZE 16
#define SERIAL_RX_BUFFER_SIZE 16
#else
#define SERIAL_TX_BUFFER_SIZE 64
#define SERIAL_RX_BUFFER_SIZE 64
#endif
#endif

to

#if (RAMEND < 1000)
#define SERIAL_TX_BUFFER_SIZE 400
#define SERIAL_RX_BUFFER_SIZE 400
#else
#define SERIAL_TX_BUFFER_SIZE 400
#define SERIAL_RX_BUFFER_SIZE 400
#endif
#endif

Using 3G module with AT commands in Raspberry Pi

The first thing we are going to do with the module is to check the basic AT commands in gateway mode. Using gateway mode, commands can be sent from our Raspberry Pi directly to any serial module. To stablish UART connection with the module you can use several programs as cutecom in Raspbian graphical environment or minicom in a terminal window in order to use it via SSH . For using minicom follow these steps:

    1. Place the Arduino/RPI jumper in the 3G shield to the right, in RPI position.
    2. Place the two Serial com. jumpers in the 3G shield to the left, in Arduino position. These jumpers always have to be in this position, in gateway mode and when you run codes.
    3. We recommend to power externally the shield, but it’s not necessary in all cases.

      If you decide not to use an external power supply you must set the “Vin ext. Jumper” to the left, in “Arduino 5V position” and do not forget to place the switch in the Raspberry connection bridge to the right.

      If you choose to use an external power supply of 5V or 12V you must place it through the Vin pin, (in the shield, it is placed where Arduino has the Vin pin), the “Vin ext. jumper” must be set to the right, in “Vin position”. The power supply must be able to provide sufficient current up to 2A. Besides this, do not forget to place the switch in the Raspberry connection bridge to the left.

      You can check our FAQ about 3G/Sim900/Sim908 here.

    4. Connect the shield to the Raspberry Pi connection bridge and the antennas to the shield. Now press the ON button in the shield, you will see a green LED.

  1. Open a Terminal window on Raspberry Pi, or connect to Raspberry Pi through SSH. In order to enter via SSH change here the IP from your Raspberry Pi. The default user is pi.
    ssh -X pi@192.168.1.X

    Now you will have to type your password. The default password is “raspberry”.

  2. Install minicom (only if you haven’t done it before):
    sudo apt-get install minicom
  3. Open comunication with the module UART, the baudrate is 115200:
    minicom -b 115200 -o -D /dev/ttyAMA0
  4. Then if you type AT you’ll get OK, this means that the communication with the module is working fine. Now, with the module working you can check some AT commands to control the module.
  5. To exit minicom press CTRL+A, then press X and Yes.

6. Using 3G module like a modemGo to index

If you want to use the 3G module such a modem, please refer to the next link:

3G modem tutorial

7. AudioGo to index

Audio features

SIM5218 module provides two analogy inputs for microphone and three analogy outputs for two speakers and headphones. Depending of the selected audio channel (normal, headset and hands-free) a specific input and output are activated. The different channels are selected with the command AT+CSDVC.

Normal channel (AT+CSDVC=1) uses the main microphone and a speaker. Headset channel (AT+CSDVC=2) uses the jack connector. Hand-free channel (AT+CSDVC=3) uses the main microphone and the loudspeaker.

Both microphones don’t need an external power source because they are powered directly by the module. You can use some extra commands in your codes like noise suppression, echo canceller or the gain of the mic amps. Please, refer to the AT command document list at the end of this article for more information.

Audio connectors

Audio connectors are situated at the bottom of the board. The two speakers and the main microphone are connected to board using pin connectors.

3G/GPRS shield for Arduino (3G + GPS) + Audio/Video Kit

Headset connector are situated at the bottom too, between Arduino board and 3G board.

This connector has 4 terminals that correspond with the positive terminal of the microphone, left and rigth headphones and common ground. The order of connections show below.

Originating and receiving voice calls

The code example and the connection diagram shown below are used to originate a voice call and, pushing a button, end that voice call. The button is connected between digital pin 12 an ground. A 10kΩ pull-up resistor is needed at this pin.

Arduino:

Show code
Code:

Raspberry Pi:

Show code
Code:

To make a lost call next code is used.

Arduino:

Show code
Code:

Raspberry Pi:

Show code
Code:

To receive calls the used code are this and the connection diagram is the same that the used to originate calls. Don’t forget the pull-up resistor on pin 12.

Arduino:

Show code
Code:

Raspberry Pi:

Show code
Code:

The channel may be changed during a call. Use the command AT+CSDVC to select the channel that you want.

Recording and playing sound

With the next code we can record a sound, stores it and before play it. You can select the place to store the sound clip: the local storage or a SD card. Once saved the sound can be sent to an FTP or FTPS as you’ll see later.

Arduino:

Show code
Code:

Raspberry Pi:

Show code
Code:

Also, you can use the 3G module like a mp3 player! First, you must save your music in mp3, amr or qcp format. You can use Audacity (linux) or Mobile Media Converter (Windows or Linux) to do this. Then, save the music in the Audio folder on microSD card. Now, put microSD card into the shield and enjoy the music!

NOTE: You will need to update your firmware to play mp3. The update is available here. Uncompress and run it in a PC with Windows (emulated Windows not supported).

A voice call can be recorded using these same commands too.

Command summary

Command Response Description
AT+CPTONE=** OK Plays a DTMF tone or complex tone on local voice channel device . ** is the number of the tone.
ATD*********; ********* is the number to call.
ATA OK Answer an incoming call.
AT+CHUP OK Cancel voice calls.
AT+CNSM OK Enable/disable noise suppression.
AT+CQCPREC=*,&&& Starts recording sound clips . Answers with the path and the name of the clip. * is the path and &&& is the format.
AT+CQCPPAUSE OK Pauses record sound.
AT+CQCPRESUME OK Resumes record sound.
AT+CQCPSTOP OK Stops record sound.
AT+CCMXPLAY=”*****” OK Plays an audio file . ***** is the name of the file.
AT+CCMXPAUSE OK Pauses playing audio file.
AT+CCMXRESUME OK Resumes playing audio file.
AT+CCMXSTOP OK Stops playing audio file.

8. CameraGo to index

We have modified the 3G Shield to make it work with a better camera. So instead of using the old 0’3MP Camera, now the shield supports a 2MP Camera, improving the resolution from 640 x 480 (VGA) to 1600 x 1200 (UXGA)!

Comparative:

Old Camera New Camera
Resolution 0.3 MP 2 MP
Sensor OV7725 OV2640
Max. resolution 640 x 480 (VGA) 1600 x 1200 (UXGA)
Image area 3984 µm x 2952 µm 3590 µm x 2684 µm
Sensitivity 3800 mV/Lux-sec 0.6 V/Lux-sec
Optical format 1/4″ 1/4″
Power 120 mW 140 mW

Click in the next photos to enlarge (left click):

Old photo

New photo

The new 2MP Camera is included in the Audio / Video 3G Kit. You can also get directly the 2MP Camera here.

NOTE: The new 2MP Camera can be used only in the last version of the 3G Shield. The old 0’3MP camera can not be used in the new version of the 3G Shield.

NOTE: The 2MP resolution of 1600 x 1200 is just for photos. Video recording is performed at 320 x 240 due to module restrictions.

How do I know if my 3G Shield is compatible with the new 2MP Camera?

  • Check your serial ID. The sticker included in the shield tells you the number of batch. The new 2MP Camera is compatible with batches xxxx-0010-xxx and above.

  • Date of Order. For orders starting in June 2014 all the 3G Shields sold are compatible with the new 2MP Camera.

Camera features

This module allows to connect a camera for video recording and taking photos. Once saved the video or image file can be sent to an FTP or FTPS as you’ll see later. The pin diagram shows below:

Pin nº Name Pin nº Name Pin nº Name
1 NC 9 HSYNC 17 PCLK
2 AGND 10 DVDD 18 DATA6
3 SDA 11 DOVDD 19 DATA2
4 AVDD 12 DATA9 20 DATA5
5 SCL 13 MCLK 21 DATA3
6 RESET 14 DATA8 22 DATA4
7 VSYNC 15 AGND 23 DATA1
8 PWDN 16 DATA7 24 DATA0

Mounting the camera

Follow these simple steps to mount the camera into the 3G Arduino board.

The first step is to open the socket. To do this, pull carefully out the sides of the connector.

Inserts the camera with metallic contacts facing up

At the final step, push in the laterals of the connector.

The camera may get hot if continuous usage is performed. Maximum operation temperature is 45ºC.

Video recording

To record video, and take images, you must start the camera in the first step. After you can configure some parameters like resolution, fps, rotation or zoom. The next code allows to record a video file in mp4 format. Remember, if you want to store the video file in a SD card, you must to use AT+FSLOCA command.

Arduino:

Show code
Code:

Raspberry Pi:

Show code
Code:

Taking photos

Take photos is very easy, here is the example code:

Arduino:

Show code
Code:

Raspberry Pi:

Show code
Code:

Video call

The SIM5218 allows video calls, but to carry them out correctly the operator and the network must be able to allow it. The example code is below. Cooking Hacks not ensure that the video call functions correctly.

Please, be sure that your SIM card have activated the videocall feature, with your network operator and with the phone that you want to call, before to test the next sketch.

Arduino:

Show code
Code:

Raspberry Pi:

Show code
Code:

Command summary

Command Response Description
AT+CCAMS OK Starts camera.
AT+CCAME OK Stops camera.
AT+CCAMSETD=xxx,yyy OK Sets dimension of camera. xxx is the width and yyy is the height.
AT+CCAMSETF=* OK Sets the frames per second. * is the frame rate option.
AT+CCAMRS OK Starts video recording . Also responds with the path and name of the file.
AT+CCAMRP OK Pauses the record.
AT+CCAMRR OK Resumes video record.
AT+CCAMRE OK Stops video record.
AT+CCAMTP OK Takes a picture.
AT+CCAMEP OK Saves a picture taken by last AT+CCAMTP. Also responds with the path and name of the file.
AT+VPMAKE Makes a video call.
AT+VPEND Ends a video call.

9. GPSGo to index

SIM5218 supports both A-GPS and S-GPS and provides three operating modes: mobile-assisted mode, mobile-based mode and standalone mode. A-GPS is include mobile-assisted and mobile-based mode.

In mobile-assisted mode, when a request for position location is issued, available network information is provided to the location server (e.g., Cell-ID) and assistance is requested from the location server. The location server sends the assistance information to the handset. The handset/mobile unit measures the GPS observables and provides the GPS measurements along with available network data (that is appropriate for the given air interface technology) to the location server. The location server then calculates the position location and returns results to the requesting entity.

In mobile-based mode, the assistance data provided by the location server encompasses not only the information required to assist the handset in measuring the satellite signals, but also the information required to calculate the handset’s position. Therefore, rather than provide the GPS measurements and available network data back to the location server, the mobile calculates the location on the handset and passes the result to the requesting entity.

In standalone (autonomous) mode, the handset demodulates the data directly from the GPS satellites. This mode has some reduced cold-start sensitivity, and a longer time to first fix as compared to the assisted modes. However, it requires no server interaction and works out of network coverage.

This combination of GPS measurements and available network information provides:

  • High-sensitivity solution that works in all terrains: indoor, outdoor, urban, and rural
  • High availability that is enabled by using both satellite and network information

Therefore, while network solutions typically perform poorly in rural areas and areas of poor cell geometry/density, and while unassisted, GPS-only solutions typically perform poorly indoors, the SIM5218 GPS solution provides optimal time to fix, accuracy, sensitivity, availability, and reduced network utilization in both of these environments, depending on the given condition.

Stand-alone mode

In this mode, the GPS obtains position, altitude,… with only the signal of the satellites, making it the slowest of the three modes. If you use the AT+CGPSINFO command, the module bring directly latitud, logitude, date, UTC time, altitude and speed. Here is the example code:

Arduino:

Show code
Code:

Raspberry Pi:

Show code
Code:

If you want to get the NMEA sentences, you must to use the command AT+CGPSSWITCH=1 and configure the UART port at 57600 bauds. Supported NMEA sentences include GSV, GGA, RMC, GSA, and VTG.

S-GPS mode

For the S-GPS the module connects to a GPS server and the module calculates the position. Here is the example code:

Arduino:

Show code
Code:

Raspberry Pi:

Show code
Code:

A-GPS mode

For the A-GPS the module connects to a GPS server for calculate the position. Here is the example code:

MS-assisted Server Module
Location server sends aiding data that is valid for the current fix Sending data
Module sends code phases Code phases
Server calculates position Calculate position
MS-based Server Module
Location server sends aiding data that is valid for the current fix Send aiding data
Module calculates Calculate position
Stand alone Server Module
Module demodulates data form GPS satellite Demodulates GPS satellite data
Module calculates position Calculate position

GPS units

The command AT+CGPSINFO returns the GPS info in a string:

+CGPSINFO: [<latitude>],[<N/S>],[<longitude>],[<E/W>],[<date>],[<UTC_time>],[<altitude>],[<speedOG>],[<course>]

Values Format Example
latitude ddmm.mmmmmm

d: degree; m: minute

4140.831527
longitude dddmm.mmmmmm

d: degree; m: minute

00053.173495
date ddmmyy

d: day; m: month; y: year

020812
UTC_time hhmmss.s

h: hour; m: minute; s: seconds

083418.0
altitude meters 257.00
speedOG knots 2
course degrees 0

If UE-assisted mode, when fixed will report indication:

+CAGPSINFO:<latitude>,<longitude>,<altitude>,<date>,<UTC_time>

Values Format Example
latitude Unit is in 10^8 degree 4168050885
longitude Unit is in 10^8 degree 88618039
altitude meters 293
date ddmmyyyy
d: day; m: month; y: year
28092012
UTC_time hhmmss.s
h: hour; m: minute; s: seconds
081611.0

Command summary

Command Response Description
AT+CGSOCKCONT=**,&&& OK ** is the protocol and &&& Access Point Name.
AT+CGPS=*,& OK * sets on (1) or off (0) and & is the GPS mode.
AT+CGPSINFO Gets current position information.
AT+CGPSURL=”***” OK Sets AGPS default server URL . *** is the URL.
AT+CGPSSSL=* OK Select transport security, used certificate (*=1) or not (*=0).
AT+CGPSSWITCH OK Choose the output port for NMEA sentence.

10. SMSGo to index

Sending and receiving SMS

The first code is used to send a SMS, the second one reads the SIM message memory and shows the last SMS.

Arduino:

Show code
Code:

Raspberry Pi:

Show code
Code:

Arduino:

Show code
Code:

Raspberry Pi:

Show code
Code:

Command summary

Command Response Description
AT+CMGF= OK Specifies the input and output format of the short messages. 0 for PDU mode and 1 for text mode.
AT+CMGS Sends a message.
AT+CPMS=*** Selects memory storages. *** is the memory type.
AT+CMGR=* Reads a message. * is the number of the message.

11. E-mailsGo to index

Sending an e-mail

To send e-mail a SMTP server is used, so we need an e-mail account. The code example is the next:

Arduino:

Show code
Code:

Raspberry Pi:

Show code
Code:

Receiving an e-mail

For read an e-mail from a POP3 server we need an e-mail account. The code example is here:

Arduino:

Show code
Code:

Raspberry Pi:

Show code
Code:

Command summary

Command Response Description
AT+CGSOCKCONT=**,&&& OK ** is the protocol and &&& Access Point Name.
AT+SMTPSRV=”*****”,&&& OK Sets SMTP server address and server’s port . ***** is the sever address and &&& is the server’s port.
AT+SMTPAUTH=1,”***”,”&&&” OK Controls SMTP authentication. *** is the user name and &&& is the password.
AT+SMTPFROM=”***”,”&&&” OK Sets sender’s address and nam e. *** is the sender’s address and &&& is the sender’s name.
AT+SMTPRCPT=x,”***”,”&&&” OK Sets recipient address/name and kind . x is the kind (TO/CC/BCC), *** is the recipient address and &&& is the recipient name.
AT+SMTPSUB=”****” OK Sets the subject of e-mail . **** is the subject.
AT+SMTPBODY Sets e-mail body.
AT+SMTPSEND Initiates TCP session with SMTP server and sends an e-mail
AT+POP3SRV=”**”,”&&”,”xx”,yy OK Sets all parameters to get an e-mail from POP3 . ** is the server address, && is the user name, xx is the password and yy the server port
AT+POP3IN OK Logs in POP3 server
AT+POP3GET=*** Gets an e-mail from POP3 server , *** is the number of the e-mail.
AT+POP3OUT OK Logs out POP3 server
AT+POP3READ=”***”,”&&&” Reads an e-mail from file system . *** is the location and &&& is the name.

12. SD and system memoryGo to index

The file system is used to store files in a hierarchical (tree) structure. Local storage space is mapped to “C:”, and SD is mapped to “D:”. In both “C:” and “D:” directories, module creates four directories named “Picture”, “Audio”, “Video” and “VideoCall” automatically; “Picture” is used to store static image when taking picture by camera, “Audio” is used to store audio file, “Video” is used to store video file when recor ding by camera, and “VideoCall” is used to store media file which is recorded during a video call.

The maximum size of the microSD card is 32GB. Here are some AT commands to manage the file system:

AT command Response Description
AT+FSCD=**** OK Select a directory as current directory . **** is the directory.
AT+FSMKDIR=**** OK Create a new directory in current directory . **** is the name of the new directory.
AT+FSRMDIR=**** OK Delete existing directory in current directory . **** is the name of the directory to delete.
AT+FSLS Make a list with informations of directories and/or files in current directory.
AT+DEL=**** OK Delete a file in current directory. **** is the name of the file to delete.
AT+FSRENAME=****,&&& OK Rename a file in current directory. **** is the actual name and &&& is the new name.
AT+FSATTRI=**** Request the attributes of file which is existing in current directory. **** is the name of the file.
AT+FSMEM Check the size of available memory.
AT+FSFMT OK Format storage card which is plugged in.
AT+FSLOCA= OK Set the storage place , 0 for local and 1 for SD

13. FTP and FTPSGo to index

FTP

Creating a file into the FTP server, writing it and reading it.

Arduino:

Show code
Code:

Raspberry Pi:

Show code
Code:

Uploading a file from local storage or SD to FTP server.

Arduino:

Show code
Code:

Raspberry Pi:

Show code
Code:

Downloading a file from FTP server or SD to local storage.

Arduino:

Show code
Code:

Raspberry Pi:

Show code
Code:

FTPS

Creating a file into the FTP server, writing it and reading it (likes FTP codes)

Arduino:

Show code
Code:

Raspberry Pi:

Show code
Code:

Uploading a file from local storage or SD to FTP server

Arduino:

Show code
Code:

Raspberry Pi:

Show code
Code:

Downloading a file from FTPS server or SD to local storage

Arduino:

Show code
Code:

Raspberry Pi:

Show code
Code:

Command summary

AT command Response Description
AT+CGSOCKCONT=**,&&& OK ** is the protocol and &&& Access Point Name.
AT+CFTPSERV=”****” Sets FTP server domain name or IP address. **** is the domain name or the IP.
AT+CFTPPORT=*** OK Sets FTP server port. *** is the port.
AT+CFTPUN=”***” OK Sets user name for FTP server access. *** is the user name.
AT+CFTPPW=”***” OK Sets password for FTP server access. *** is the password.
AT+CFTPMODE= OK Sets FTP mode. 1 for passive or 0 for proactive.
AT+CFTPTYPE= OK Sets the transfer type on FTP server . A for ASCII or I for binary.
AT+CFTPPUT=”***”,&& Puts a file from FTP server to serial port . *** is the path with the name of the file and && is the length.
AT+CFTPGET=”***” Gets a file from FTP server to serial port . *** is the path with the name of the file.
AT+CFTPPUTFILE=”***”,& Uploads a file to FTP server from module . *** is the path and & is the storage directory.
AT+CFTPGETFILE”=***”,& Downloads a file from FTP server to module . *** is the path with the name and & is the storage directory.
AT+CFTPSSTART OK Acquires FTPS protocol stack.
AT+CFTPSLOGIN=”**”,&&&,”xxx”,”yyy” OK Logs in FTPS server. *** is the host address, &&& is the port, xxx is the user name and yyy is the password.
AT+CFTPSTYPE= OK Sets the transfer type on FTPS server . A for ASCII or I for binary.
AT+CFTPSPUT=”***”,&& Puts a file from FTPS server to serial port . *** is the path with the name of the file and && is the length.
AT+CFTPSGET=”***” Gets a file from FTPS server to serial port . *** is the path with the name of the file.
AT+CFTPSPUTFILE=”***”,& Uploads a file to FTPS server from module . *** is the path and & is the storage directory.
AT+CFTPSGETFILE=”***”,& Downloads a file from FTPS server to module . *** is the path with the name and & is the storage directory.

14. TCP and UDPGo to index

UDP client

Sending data to a UDP server:

Arduino:

Show code
Code:

Raspberry Pi:

Show code
Code:

TCP client

Sending data to a TCP server:

Arduino:

Show code
Code:

Raspberry Pi:

Show code
Code:

Multiclient

SIM5218 allows to use ten connections simultaneously. Here is the example code with a UDP and TCP connections.

Arduino:

Show code
Code:

Raspberry Pi:

Show code
Code:

TCP server

SIM5218 allows to create a TCP server with a maximum of ten TCP clients. In this example the server send a message every 5 seconds to all clients.

Arduino:

Show code
Code:

Raspberry Pi:

Show code
Code:

Command summary

AT command Response Description
AT+NETOPEN=”***”,&& Opens a socket . *** is the socket type and && is the port.
AT+NETCLOSE OK Closes socket.
AT+UPDSEND Sends UDP data.
AT+TCPCONNECT=”***”,&& Establishes TCP connection with TCP server. *** is the IP address and && is the port.
AT+TCPWRITE Sends TCP data when the TCP connection is established.
AT+SERVERSTART OK Starts up TCP server.
AT+LISTCLIENT Lists all of clients’ information.
AT+ACTCLIENT=* OK Activates the specified client. * is the number of the client.
AT+CLOSECLIENT=* OK Disconnects the specified client. * is the number of the client.
AT+CIPOPEN=*,”&&”,”xx”,yy Establish a connection with TCP server or UDP server. * is the number of the connection, && is the type of transmision protocol, xx is the server IP and yy is the server port.
AT+CIPSEND Sends some data to remote host in mult-client mode.
AT+CIPCLOSE=* OK Closes a specified connection in multi-client mode. * is the number of the connection.

15. HTTP AND HTTPSGo to index

HTTP

SIM5218 can launch a HTTP operation like GET or POST. Here is an example with GET operation. As you can read in the header of the code, you will need to increase the buffer size to 400 bytes.

Arduino:

Show code
Code:

Raspberry Pi:

Show code
Code:

HTTPS

Arduino:

Show code
Code:

Raspberry Pi:

Show code
Code:

Command summary

AT command Response Description
AT+CHTTPACT=”***”,&& Launches a HTTP operation . *** is the server address and && is the port.
AT+CHTTPSSTART OK Acquires HTTPS protocol stack.
AT+CHTTPSSTOP OK Releases HTTPS protocol stack.
AT+CHTTPSOPSE OK Opens a new HTTPS session.
AT+CHTTPSCLSE OK Closes the opened HTTPS session.
AT+CHTTPSSEND=* Sends HTTPS request. * is the length of the data in the sending buffer.
AT+CHTTPSRECV=* Receives HTTPS response after sending HTTPS request.

16. Fritzing LibrariesGo to index

The new 3G shield for Arduino enables the connectivity to high speed WCDMA and HSPA cellular networks in order to make possible the creation of the next level of worldwide interactivity projects inside the new “Internet of Things” era.

You can download our Fritzing libraries from this area.

17. Video-TutorialGo to index

Here’s an explanatory video, which shows the whole process developed in this tutorial:

Check the GPS+PIC Code here:

Arduino:

Show code
Code:

Raspberry Pi:

Show code
Code:

永不消逝的电波

$
0
0

永不消逝的电波(一):无线电入门篇

2015-09-16157511人围观,发现39个不明物体无线安全极客

文/漏洞盒子安全团队-雪碧

0×00 无线电发展简史

· 1837年,摩斯发明了电报,创造了摩斯密码(Morse code),开始了通信的新纪元。
· 1865年,英国的麦克斯韦总结了前人的科学成果,提出电磁波学说。 
· 1876年,贝尔发明了电话,能够直接将语言信号变为电能沿导线传送。 
· 1887年,德国科学家赫兹(Hertz)用一个振荡偶子产生了电磁波,在历史上第一次直接验证了电磁波的存在。 
· 1897年,意大利科学家马可尼(Marconi)在赫兹实验的基础上,实现了远距离无线电信号的传送,这个距离在当时不过一百码,但一年后他就实现了船只与海岸的通信。 
· 1901年12月12日,马可尼做了跨越大西洋传送无线电信号的表演。这一次他把信号从英国的Cornwall发送到加拿大的Newfoundland。 马可尼因此获得1909年度诺贝尔奖。与他分享这一年度诺贝尔奖的是布劳恩(Braun),因为布氏发现金属硫化物具有单向导电性,这一成果可用于无线电接收装置。 
· 1904年,英国科学家弗莱明(Fleming)获得了一项专利,在专利说明书中描述了一个高频交变电流整流用的两极真空管,标志着进入无线电电子学时代。  
· 1906年,美国科学家弗雷斯特(Forest)发明了真空三极管,是电子技术发展史上第一个重要里程碑。同年,美国科学家费森登(Fessenden)在Massachusetts领导了第一次广播。 
· 1912年,英国科学家埃克尔斯(Eccles)提出了无线电波通过电离层传播的理论,这一理论使得一群业余爱好者在1921年实现了短波试验性广播; 同年,美国的费森登(Fessenden)和阿姆斯特朗(Armstrong)改进了接收机的工作方式,发明了外差式接受系统,这种形式仍是目前许多无线电接收机的主要工作方式。

在新中国成立后相当长的一个时期内,由于考虑国家安全等问题,国家对无线电台实行“少设严管”的政策,无线电台成为军队、邮电、广播、公安和交通等国家要害部门进行信息通信的重要工具。改革开放以后,各种无线电新技术、新业务在国民经济和社会生活的各个领域得到了越来越广泛的应用,我国逐步成为全球无线电应用大国。

近年来,国际电联划分的43 多种无线电业务,已在我国通信、广电、铁路、交通、航空、航天、气象、渔业、科研等行业和领域得到广泛应用,有力地推动了经济和社会发展的进程。

0×01 电磁波与无线电

1. 混为一谈OR完全割裂

有人会把电磁波、光、无线电波混为一谈,也有人会把它们完全割裂开来,这些都是不正确的。

在快速变化的电流周围会产生电磁波,为了描述电磁波的特征,科学家们引入了频率、波长、波速三个物理参数:

物理量       概念                          单位
频率(f)    电磁波1s振荡的次数             赫兹(Hz)
波长(λ)    电磁波每振荡一次向前传播的距离  米(m)
波速(c)    电磁波每1s向前传播的距离       米/秒(m/s)

公式    C=λf(波速=波长×频率)

2. 电磁波波段划分:

L波段、S波段、C波段、X波段、Ku波段、K波段、Ka波段。

这种划分方式是雷达业内的通俗叫法,没有一个严格、统一的标准。通常的划分是:

L波段 1~2GHz;
S波段 2~4GHz;
C波段 4~8GHz;
X波段 8~12GHz;
Ku波段 12~18GHz;
K波段 18~27GHz;
Ka波段 27~40GHz;
U波段 40~60GHz;
V波段 60~80GHz;
W波段 80~100GHz.

3. 电磁波的速度&分类:

电磁波产生之后,传播时不需要任何介质,在真空中也能传播,其在真空中传播速度为固定值,是宇宙中物质运动的最快速度,与光速相同,数值为3×10^8 (3乘10的八次方) m/s;

电磁波根据波长的大小,分为短波、中波、长波、微波、红外线、可见光、紫外线、Χ射线、γ射线等。

4. 无线电波传播途径:

无线电波广泛地应用于无线电通讯、广播、电视等方面,无线电波的发射和接受通过天线实现,其传播分为三种途径:天波、地波、微波。

地波:沿地球表面空间传播的无线电波叫做地波。由于地球是一个大导体,地球表面会因地波的传播引起感应电流,因此地波在传播过程中要损失能量,频率越高损失的能量也越多,所以地波主要适用于长波、中波和中短波。
天波:依靠电离层的反射来传播的无线电波叫做天波。电离层对于不同波长的电磁波的反射和吸收表现不同的特性,波长越长,吸收越强反射越弱,因此短波最适宜以天波的形式传播。
微波:微波是由于频率高、波长短,它既不能以地波的形式传播,又不能依靠天波的形式传播,和光一样,沿直线传播。

5. 无线电与电磁波

频率在数百千赫兹到数百兆赫兹之间的电磁波叫做无线电波,它包括短波、中波、长波、微波,无线电波也仅仅是电磁波的一部分,但电磁波不仅仅只有无线电波,仅仅只有频率相对较低的一部分电磁波才叫无线电波。

0×02 无线电信号调制

1. 什么叫调制,为什么要调制?

声音的频率是20HZ-20KHZ,转变成电磁波后也是这个频率,属于低频。电磁波的频率越高越容易传送得更远。所以音频需搭载在高频信号上才能传输得更远,音频搭载上高频信号的过程就叫调制。

调频波波形

无线电信号是原始信号和已调振荡信号的总称。声音、图像、文字、电码等欲传送的信息,通过转换设备后,转变成为相应变化的电压或电流,这种变化的电压或电流称为原始信号。在发射机中原始信号是用来调制高频振荡的,或者说是用来控制高频振荡的某一参数的,因此又称为调制信号或控制信号。经过调制的高频振荡,或者说参数按调制信号规律变化的高频振荡,称为已调振荡(已调波)。

调制的目的是为了把音频传送到更远的地方。目前常用的方法有调幅(AM)和调频(FM)两种方法。

AM(Amplitude Modulation 调幅):调制幅度,高频信号的幅度随着音频信号幅度的改变而改变,当音频信号的幅度高时高频信号的幅度也跟着高,反之跟着变低,形成音频信号的幅度包络,但高频信号的频率保持不变;调幅的特点是频宽宽,距离短。频宽宽的意思是对阻碍物的穿透能力强,但是传输距离较短
FM(Frequency Modulation 调频):调制频率,高频信号的频率随着音频信号幅度的改变而改变,当音频信号的幅度高时高频信号的频率也跟着高,反之跟着变低,但高频信号的幅度保持不变。调频的特点是频宽窄,距离长。频宽窄的意思是对阻碍物的穿透能力弱,但是传输距离长。

注:

频率:波在一定时间内震动次数
幅度:波在震动时候上下的幅度大小
调制器:    用于实现调制信号对高频载波信号的调制,产生已调波输出。
高频放大器:    对产生的已调波进行功率及幅度的放大后送至天线发射出去。
电源:    为电路各个部分提供电源。

数字信号波形

0×03 日常生活中的无线电

1. 收音机(无线广播)

在一般的收音机或收录音机上都有AM及FM波段,这两个波段是用于收听国内广播的,若收音机上还有SW波段时,那么除了国内短波电台之外,还可以收听到世界各国的广播电台节目。

一般中波广播(MW: Medium Wave)采用了调幅(AM)的方式,在不知不觉中,MW及AM之间就划上了等号。实际上MW只是诸多利用AM调制方式的一种广播,像在高频(3-30MHz)中的国际短波广播所使用的调制方式也是AM,甚至比调频广播更高频率的航空导航通讯(116-136MHz)也是采用AM的方式,只是我们日常所说的AM波段指的就是中波广播(MW)。

2. 遥控器

3. 路由器

频率:2.4GHz、5GHz

双频路由:2.4G&5GHz


4. 卫星天线

目前,卫星电视广播采用了三种方式:

一、通过普通的通信卫星将模拟或数字电视信号转发到本地电视台、有线电视网或集体接收站进入千家万户;
二、采用模拟技术,使用大功率电视直播卫星直接向家庭广播电视信号,由于这种电视信号未经数字压缩处理,每个转发器只能直播一路电视节目信号,每颗卫星一般只能直播几路电视节目;
三、采用Ku频段数字视频压缩卫星电视直播。每个卫星转发器可向装有约为0.5~0.8m左右的小口径卫星接收天线的家庭直播5~8路电视节目,一颗卫星可以直播100多路电视信号。这种业务亦称卫星数字电视直播(DVB-S);
随着航天技术、数字电视技术、微电子技术、码率压缩技术的突破性进展,使卫星电视由原来的C频段转播进入了数字Ku频段的直播卫星阶段。卫星数字电视直播的发展已成为全球热点。

C波段天线&Ku波段天线

c波段卫星 机顶盒的大锅 直径1.2米

户户通(村村通)直播星小锅 直径0.3米

卫星天线的一些小知识:

· 在卫星通信中,要先从地面站向卫星上发送通信信号,叫上行,经过卫星上的星载设备进行放大,再发送回地面的另一个接收站接收,叫下行。
· 为防止上行和下行频率重叠干扰,系统中上行和下行各采用一个频率进行发送,从地面向卫星发送上行信号的频率叫上行频率,从卫星向地面发送下行信号的频率叫下行频率。

· 卫星天线调试参数:本振频率、下行频率、符号率、极化方式,不过目前大多数机顶盒自带自动搜索功能,所以这些参数无需牢记。

亚洲七号卫星部分节目参数

近期FreeBuf报道也曾报道过,APT 组织 Turla 使用基于卫星的通信实现 C&C

上面提及的间谍组织使用使用了DVB-S调制器(下图):

这里我们稍微了解一下:DVB-S(ETS300421) 数字卫星广播系统标准。

特点:卫星传输具有覆盖面广、节目容量大等特点。数据流的调制采用四相相移键控调制(QPSK)方式,工作频率为11/12GHz。

FreeBuf也曾报道过,今年的BlackHat大会上也有个卫星相关的议题《利用卫星接收器扩展僵尸网络》。

5. 机场塔台与飞机

一般来说,降落的灰机高度在6K的时候会通过无线电与机场塔台联系,首次联系时会向机场塔台报告本次航班的编号、已经收到的机场通播编号等(起飞的时候灰机和塔台之间也会有通信联系)。

然后机场塔台会回复该航班,是否已经从雷达上看到该航班、该航班应继续进行的操作(例如保持目前航向等),然后该航班会重复一次机场塔台刚刚发布的指挥信息。这就完成了一次联系。

机场塔台&飞机

参考知乎:机场塔台的无线电环境有什么要求?在其周围私设电台会对塔台和飞机通讯造成哪些影响?

我国民航使用的无线电频率:1090MHz

民用对讲机使用的无线电频率:408-409MHz

警用频率:350-390MHz

0×04 使用软件无线电接收飞机信号

1. 接收飞机信号的常用设备

电视棒

优势:廉价(四五十元) 接地气

不足:只能接收、不能发射信号

HackRf

优势:开源、可以接收、发射信号

不足:USB2.0传输速率低于接收速率

其它设备:bladeRF 

优势:USB3.0;支持300MHz到3.8GHz

缺陷:最高只能支持 3.8GHz,不可能用bladeRF来实现5GHz频段的802.11n

电视棒的核心芯片:

淘宝搜索”电视棒”一词是被屏蔽的,想买的同学可以搜电视棒的芯片名:“RTL2832U”。

USB DVB-T & RTL-SDR Realtek RTL2832U & R820T,这是螃蟹( Realtek)的一个芯片型号,原本是做电视棒芯片的。

后来被人发现这个芯片具有非常广的频率接收范围,然后就被用来做sdr应用了,rtl的sdr应用。

其实,某宝两三百的无线电接收器也是根据电视棒芯片改装的。

(都是用的RTL2832U。左边价格三百,右边四十多,知道真相的我曾经哭晕在厕所)

2. 电视棒使用的一些软件

硬件有了,那么软件呢?

Linux:(Ubuntu)环境搭建

硬件驱动:rtl-sdr

接收信号&解码:dump 1090

sudo apt-get install git
sudo apt-get install cmake
git clone https://github.com/pinkavaj/rtl-sdr.git
cd rtl-sdr/ 
mkdir build 
cd build
cmake ../
make 
sudo make install 
sudo ldconfig

编译安装dump 1090:

git clone https://github.com/antirez/dump1090.git 
cd dump1090/ 
make

软件启动:

cd /home/$user/dump1090 #转到dump 1090的主目录
sudo ./ dump1090 --interactive --net

软件截图:

软件界面参数:

HEX:16进制数据
Flight:航班号
Altitude:灰行高度(海拔)
Speed:灰行速度
Lat/Lon:地理坐标(经纬度数)

dump启动时会开启自带的WEB服务器,并且WEB调用了谷歌地图的API 接收到飞机的一些信息后 会在页面地图上描绘出飞机的轨迹(谷歌地图目前需要翻墙):

Windows:

驱动-zadig:类似于驱动精灵。可以在win上安装电视棒、HackRf的驱动;

sdrsharp:可以用来听广播&录制无线电信号 并把信号保存为音频文件;

HDSDR:把音频转化为信号,可配合HackRF使用进行信号输出;

rtl1090:可以接收灰机信号;

Audacity:音频分析(信号分析);

另外,之前在网上查阅资料的时候看到一张图片,思路很Nice:(原文使用HACKRF巡视钓鱼岛(HACKRF ADS-B out) )

理论上来说,这种思路是可以实现的,但是法律上不可能允许民众私自占用无线频段,(一定要遵守无线电管理法规!一定要遵守无线电管理法规!一定要遵守无线电管理法规!重要的事情要说三遍),PS:通过无线电信号的“伪造”灰机,那么雷达那边如何才能瞒天过海?

第一篇先到这里,接下来的文章中我们将通过windows上一些软件(sdrsharp、HDSDR、Audacity)进行信号分析并使用HackRF进行简单的遥控信号重放。(其实,写完这句话的时候我的内心是崩溃的,牛皮吹大了,万一不能实现怎么破?!趴在厕所马桶上哭完,坚强地回到工位 o(╯□╰)o囧  然后终于顿悟:生命在于折腾,自己吹的牛逼流着泪也要实现!)

*参考资料:人民教育出版社 、无线电通信发展简史、新时期的无线电技术应用、维基百科、google、百度、知乎,雪碧整理发布,转载请注明来自FreeBuf黑客与极客(FreeBuf.COM)

【永不消逝的电波(二)】HackRF入门:家用无线门铃信号重放

2015-11-2275498人围观,发现19个不明物体专题无线安全

作者:雪碧 0xroot

0×00 前言

在第一篇文章:永不消逝的电波(一):无线电入门篇 我们了解了一下无线电的发展史以及无线电的一些物理知识,在第二篇里我们将用HackRF录制家用门铃的无线信号,然后重放门铃信号。

门铃从某宝买的,如图:

看到红色部分的时候,雪碧同学的表情是这样的:

好像买完什么,用不了多久就降价了,233….  我可以退货再买吗?

0×01 环境搭建:

MAC下可以用gqrx和hackrf (需要有Xcode、Mac Port的支持)

sudo port install gnuradio
sudo port install hackrf
sudo port install rtl-sdr
sudo port install gr-osmosdr
sudo port install hackrf

sudo port install gqrx

也可以参考:在Mac上安装HackRF环境

0×02 步入正题:

安装完成以后,插入HackRF,终端执行 hackrf_info:

hackrf_info 
Found HackRF board.
Board ID Number: 2 (HackRF One)
Firmware Version: git-815d1f6
Part ID Number: 0xa000cb3c 0x00664f49
Serial Number: 0x00000000 0x00000000 0x583064c0 0x2640ad4b
#通过终端启动gqrx
gqrx

按下遥控器,我们可以看到信号的频率在314.100000Mhz(读作:314.1兆赫兹)左右

1Mhz=1000000hz;
1Khz=1000hz

314.1Mhz=314100000hz;

关掉gqrx启动hackrf

hackrf_transfer Usage:

Usage:
    -<filename> # Receive data into file. 把接收到的信号、数据保存到文件中;(信号录制)
    -<filename> # Transmit data from file. 从文件中提取、发送射频信号;(信号播放)
    -# Receive data into file with WAV header and automatic name.
       # This is for SDR# compatibility and may not work with other software.
    [-f freq_hz] # Frequency in Hz [0MHz to 7250MHz].
    [-i if_freq_hz] # Intermediate Frequency (IF) in Hz [2150MHz to 2750MHz].
    [-o lo_freq_hz] # Front-end Local Oscillator (LO) frequency in Hz [84MHz to 5400MHz].
    [-m image_reject] # Image rejection filter selection, 0=bypass, 1=low pass, 2=high pass.
    [-a amp_enable] # RX/TX RF amplifier 1=Enable, 0=Disable.
    [-p antenna_enable] # Antenna port power, 1=Enable, 0=Disable.
    [-l gain_db] # RX LNA (IF) gain, 0-40dB, 8dB steps
    [-g gain_db] # RX VGA (baseband) gain, 0-62dB, 2dB steps
    [-x gain_db] # TX VGA (IF) gain, 0-47dB, 1dB steps
    [-s sample_rate_hz] # Sample rate in Hz (8/10/12.5/16/20MHz, default 10MHz).
    [-n num_samples] # Number of samples to transfer (default is unlimited).
    [-c amplitude] # CW signal source mode, amplitude 0-127 (DC value to DAC).
    [-b baseband_filter_bw_hz] # Set baseband filter bandwidth in MHz.
    Possible values: 1.75/2.5/3.5/5/5.5/6/7/8/9/10/12/14/15/20/24/28MHz, default < sample_rate_hz.
hackrf_transfer -/dev/stdout -314100000 -1 -16 -32 -8000000

没按遥控器

按下遥控器:

由于hackrf_transfer后面没带解码参数,so我们看到一堆乱码数据;

0×03 录制信号&信号分析

录制遥控的无线信号:

hackrf_transfer -r door.raw -314100000 -16 -32 -1 -8000000 -4000000

终端输出:

hackrf_transfer -r door.raw -314100000 -16 -32 -1 -8000000 -4000000
call hackrf_sample_rate_set(8000000 Hz/8.000 MHz)
call hackrf_baseband_filter_bandwidth_set(3500000 Hz/3.500 MHz)
call hackrf_set_freq(314100000 Hz/314.100 MHz)
call hackrf_set_amp_enable(1)
Stop with Ctrl-C
16.0 MiB / 1.005 sec = 15.9 MiB/second
16.0 MiB / 1.003 sec = 15.9 MiB/second
16.0 MiB / 1.004 sec = 15.9 MiB/second
16.3 MiB / 1.004 sec = 16.2 MiB/second
16.0 MiB / 1.002 sec = 16.0 MiB/second
16.0 MiB / 1.001 sec = 16.0 MiB/second
16.0 MiB / 1.004 sec = 15.9 MiB/second
16.0 MiB / 1.003 sec = 15.9 MiB/second
16.3 MiB / 1.003 sec = 16.2 MiB/second
16.0 MiB / 1.003 sec = 15.9 MiB/second
16.0 MiB / 1.005 sec = 15.9 MiB/second
^CCaught signal 2
 8.1 MiB / 0.510 sec = 15.9 MiB/second

User cancel, exiting...
Total time: 11.54724 s
hackrf_stop_rx() done
hackrf_close() done
hackrf_exit() done
fclose(fd) done
exit

—————————————萌萌的分割线—————————————题外话—————————————

信号波形分析:

这里用到的软件是Audacity,导入录制的音频信号(未压缩原始数据)

然后出现如下界面:

使用默认参数,直接导入:

中间的那部分就是按下遥控时录制到的无线信号,我们使用Audacity的放大镜放大来看:

继续放大我们可以看到:

继续放大:

再放大:

这时经验比较丰富的童鞋可以通过图形,把无线射频信号转换成二进制数据:01010101**** ,接着可以把二进制写到GRC(Gnu Radio Cpmpainon),制作一个框图,使用GNC项目重放无线信号,大致方法如下:

启动Gnu Radio Cpmpainon  :Kali Linux—->无线攻击—>Software defined Radio—>GnuRadio-Companion

源:在右侧Misc一栏找到Vector Source

通过搜索添加Repeat(old)、Moving Average、osmocom Sink

四个组件:

按照流程连线:

GNC用得不多,暂时还不上手,这种方法以后再试 :)

—————————————萌萌的分割线—————————————题外话结束—————————————

0×04 信号重放

使用hackrf_transfer重放信号:

hackrf_transfer -t door.raw -314100000 -47 -1 -8000000 -4000000

终端输出:

hackrf_transfer -t door.raw -314100000 -16 -32 -1 -8000000 -4000000
call hackrf_sample_rate_set(8000000 Hz/8.000 MHz)
call hackrf_baseband_filter_bandwidth_set(3500000 Hz/3.500 MHz)
call hackrf_set_freq(314100000 Hz/314.100 MHz)
call hackrf_set_amp_enable(1)
Stop with Ctrl-C
16.0 MiB / 1.004 sec = 15.9 MiB/second
16.0 MiB / 1.004 sec = 15.9 MiB/second
16.0 MiB / 1.003 sec = 15.9 MiB/second
16.0 MiB / 1.001 sec = 16.0 MiB/second
16.0 MiB / 1.000 sec = 16.0 MiB/second
16.3 MiB / 1.001 sec = 16.2 MiB/second
16.0 MiB / 1.003 sec = 16.0 MiB/second
16.0 MiB / 1.001 sec = 16.0 MiB/second
16.0 MiB / 1.005 sec = 15.9 MiB/second
16.0 MiB / 1.003 sec = 15.9 MiB/second
16.3 MiB / 1.003 sec = 16.2 MiB/second
 8.4 MiB / 1.004 sec =  8.4 MiB/second
 
 
Exiting... hackrf_is_streaming() result: HACKRF_ERROR_STREAMING_EXIT_CALLED (-1004)
Total time: 12.03184 s
hackrf_stop_tx() done
hackrf_close() done
hackrf_exit() done
fclose(fd) done
exit

0×05 演示视频

http://v.qq.com/iframe/player.html?vid=d0173868gnw&tiny=0&auto=0binggo

熊孩子的正确使用姿势是这样的:

for i in {1..999}; do hackrf_transfer -t door.raw -314100000 -16 -32 -1 -8000000 -4000000; done

嗯,你没看错,重复播放九百九十九次 :)

0×06 参考:

Hacking fixed key remotes

Exploring Bluetooth & iBeacons – from software to radio signals and back.

中文版:HackRF嗅探蓝牙重放iBeacons信号

GNU_Radio入门_V0.99

*本文原创作者:雪碧(0xroot),转载请注明来自FreeBuf黑客与极客(FreeBuf.COM)


Experiments with the RFM69 433MHz digital transceiver module

$
0
0

Experiments with the RFM69 433MHz digital transceiver module

Summary: 

This post is an overview of an board I’m developing which encapsulates the RFM69 radio module with a MCU to expose a simple UART API which can be tailored for specific applications. This simplifies embedding a radio into existing applications with very little additional expense in terms of hardware or power budget. The API is implemented by a light weight radio OS (currently just 5KiB) which is open source and the bill-of-materials for the board can be as little as $8 / €7.

Background to project:

WRSC2014 contestant Team FASt from University of Porto.

The World Robotic Sailing Championship 2014was held in Galway Ireland (my home town) in September this year. It was originally anticipated that each contestant would use a RFM69 radio module to relay real time positioning information back to a central hub for recording the race and scoring. It was also hoped that the race organizers could use the same radio network to broadcast race waypoints, starting times, obstacles etc. However given the short time available it became clear that race contestants would not have sufficient time to incorporate this module into their hardware and write the associated supporting firmware.

Based on the experience of WRSC 2014 I believe the best solution for such competitions is to develop a low cost ready made ‘black box’ which is given (ready made and programmed) to each contestant. The black box would expose a very simple API to the boat’s software which should not take long to integrate. Or if it’s a case the contestant simply does not have time to make any changes to their software the radio can be mated with a GPS module and it will send real time position, speed and heading back to the race organizers.

This project is the first step in such a system.  An entire race system will incorporate other elements such as base station software, real time visualization tools, race protocols etc. This blog post only discusses the radio board.

RFM69 family of modules:

The RFM range of modules are made by HopeRF and based on the Semtech radio ICs. The RFM69 comes in several varieties. The one I’ve been using is the higher power version: the RFM69HW [1] which is based on the Semtech SX1231H [2]  chip.

Feature highlights:

  • Digital SPI interface
  • Operates on 433MHz unlicensed ISM band
  • Continuous or packet mode (66 byte FIFO)
  • Built in AES encryption and CRC-16 engine
  • Configurable bit rates up to 300kbps
  • Configurable power settings
  • Line-of-sight ranges in excess of 1km
  • Sleep current < 1µA
  • Only $4 in small quantities

The radio board:

This is the general architecture of the board: a MCU acts as the go between the application hardware and software and the RFM69 radio module. The MCU takes care of all the complex register configuration of the RFM69 and takes of low level functions (such as responding to pings, remote configuration commands etc) without ever bothering the application. The application talks to the MCU thru a standard UART interface using a very simple protocol.

In addition to the core API there is also the option to compile in application specific functions (for example I’ve build in support for a rain tip-bucket and a temperature sensor: more on that later).

Prototype mk1:

Unfortunately these modules have a 2mm pad pitch making them difficult to use directly with standard 2.54mm spacing prototype board or breadboard. So for the first prototype I glued the module onto a prototype board and used thin 30AWG wire to link the module pads to pads on the protoboard.

Reasonably need looking from above…

The problem is on the underside…

Even though it’s only a hand full of wires, cutting, stripping and soldering these is very time consuming and error prone (well in excess of three hours per board).

For the first prototype I used a LPC810 ARM Cortex-M0+ MCU as the controller.  The ARM Cortex-M range is my MCU of preference these days due to the ease of 32 bit programming, open source and well supported tools and a wide range of vendors (NXP, TI, Freescale etc).

This 8 pin DIP, 4KiB program memory device was adequate for initial tests, but I quickly ran up against the 4KiB program limit. The 8 pin DIP package also had the advantage that I could socket it and try different versions of firmware just by swapping out the device.

With two of these modules I did some range tests. I soldered 17cm wire (quarter wave at 433MHz) to both sides of the board just at the RFM69 antenna output pad. I was able to achieve two way communication of about 1km along the (line-of-sight) length of the Doughiska Road in east Galway city.

Prototype mk2:

For the next prototype I moved to the LPC812: in many ways identical to the LPC810 but with more IO pins and more memory (16KiB program memory, 4KiB SRAM). Rather than use time consuming protoboard I decided it was worth spending some money on a PCB. I designed a two layer board using the free version of CadSoft Eagle and used Eurocircuit’s standard FR4 pool to fabricate. This job cost €80, but for that I got 20 boards. The turn around time was nominally 10 working days, but I had them in a week.

The board in the photo actually comprises two boards:  one for the RFM69 discussed here and another for a similar (better?) module the RFM98 which I’ll discuss in another blog post. The two halves are separated with a hacksaw.

One very handy feature of the LPC81x range of MCU is the switch matrix which allows many of the MCU functions to be mapped to an arbitrary pin.  This makes PCB layout a lot easier.

After populating with the MCU, module and 3 other components (LED, resistor and decoupling capacitor for MCU) this is what the board looks like. There is the option to use a wire as antenna, or alternatively splash out on a SMA connector (probably the most expensive component on the board!). This photo shows a SMA connector with a 433MHz stub antenna obtained from Farnell [3].

On the left is the UART connector for the radio API, pins for Serial Wire Debug (SWD) for debugging and reprogramming. Left top is the power connector (3.3V nominal, but will work down to 1.8V).

There is also a LED at the very top-left. This is a general purpose indicator that’s under control of the MCU. I use this to flash a sequence after boot up tests are complete and flash it each time a packet is sent or received.

In the center there is an option for another connector which will give direct access to the RFM69 SPI port for debugging, or simply using the PCB as a breakout board for the radio module (leaving the MCU pads unpopulated).

The bill of materials is PCB €2;  LPC812M101JD20 €1.50; RFM69HW €3 ; passives, pin headers €0.50; SMA connector (optional) €3.50 ; stub antenna (optional) €5. That’s a total of €7 without the SMA connector option. Those prices with the exception of the PCB are for single quantities from Element 14’s catalog.  Significant discounts are usually available when ordering 20+. Also components can often be sourced at a much lower cost from Chinese retailers (eg Alibaba and Deal Extreme). The PCB cost is more complex: many fabricators have a fixed job charge (it was about €50 for Eurocircuits) and they then charge per PCB after that. So if you make a lot of them the price per board goes down quickly. If you make just one it will be very expensive.

The radio OS firmware:

My firmware is written in C and currently uses the LPCXpresso IDE to build. This uses the GCC compiler under the hood. The main purpose of the firmware is to expose an simple UART API which the host application uses. The API protocol is simple: a single character command/response code followed by parameters separated by spaces followed by a carriage-return to end the command. All parameters are in hexadecimal. Example:

application to radio:
T 44 5232

‘T’ means transmit a packet. It takes two parameters: the to-address and the packet payload.

radio to application:
p FF 42 7A14051F003D AD

The ‘p’ response code is transmitted to the application whenever a packet is received. There are four parameters: the to-address (FF hex being the broadcast address),  from-address, the packet payload and the RSSI (received signal strength indicator).
Other commands include ‘R’ and ‘W’ to read/write RFM69 radio configuration registers. ‘M’ to switch operating mode from an active awake/listening (20mA current use) to a sleep-polling mode using an average of about 140µA.
Some advanced experimental commands are remote register read/write, allowing a remote radio to be reconfigured. Remote watchdog timer configuration which will reset the radio to default configuration should there be a prolonged loss of communication. Remote command execution (which can be used for remote configuration and to relay packets), remote battery voltage measurement.
Test application:
As mentioned earlier the intended application is for robot sailboat telemetry. But I’m conducting initial tests by using one of these radios with a rain tip-bucket and temperature sensor in my garden. I’ve got the radio board in an IP66 enclosure with a small PV panel and LiPo battery (and associated charger).
The tip-bucket causes a magnet to fly past a reed-switch each time the bucket tips. I use this in conjunction with one of the spare LPC812 pins and an interrupt channel to count each time this happens. I’ve also got a DS18B20 temperature sensor on another spare pin.
I run this in low power polling mode. Every 30 seconds the MCU comes out of deep sleep mode, makes a temperature measurement and fires up the transmitter and sends a status packet with the tip bucket counter, current temperature, and battery voltage [4]. It listens for about 100ms for a response packet. If none is received it goes back into deep sleep mode.
If I need to communicate to the out door unit I must wait for a poll packet and then immediately send my command. If multiple commands need to be issued, the first command is to switch the radio into active listen mode, issue all the necessary commands and then put back into low power mode.
So far tests have been successful with the only communications disruptions attributed to either running out of battery charge (it’s winter here and the days are short: unless  it’s a sunny day there is not enough stored charge to keep it going through the night) or a problem with the USB/Serial cable at the receiving end.
This is 48 hours of some sample data. The disruptions are due to problems with the USB/Serial cable at the receiving end: the radio worked flawlessly. Also note the elevated temperatures are due to the sun falling directly on the IP66 box.
Current and future work:
I’m currently working an a web browser based application/UI to interact with these radios. The application will allow configuration of the local and remote radios, performing experiments with various radio settings. Monitoring network performance etc.

Also I’m planning to make a third prototype. This will be smaller than the current board, perhaps putting the MCU on the underside of the board. I’m also considering moving to the recently announced LPC82x MCUs [ref] which feature more program flash, more SRAM, a full ADC and other new features.

Features for future firmware include mesh networking, encryption, remote program execution and over-the-air firmware upgrades.

Conclusions:

So far I’m very impressed with these radio modules. At only $4 they’re a steal. I’ve verified two way communication at over 1km distance line-of-sight and I’ve heard reports of success well in excess of 1.5km line-of-sight. With the addition of an LPC812 MCU with my radio OS and simple UART API, embedding this radio into an application is far simpler than building the radio driver directly into the application software. The entire bill of materials is about $7 with the option of a SMA connector which might bring it to $10. My PCB layout is available under the BSD licence on GitHub [5] and the firmware is also available on GitHub [6].

Footnotes:
[1] RFM69 Datasheet
http://www.hoperf.cn/upload/rf/RFM69-V1.3.pdf

[2] Semtech SX1231H product information and datasheet
http://www.semtech.com/wireless-rf/rf-transceivers/sx1231h/

[3] Farnell/Element 14 SKU 2305893, €4.86 in single quantities.

[4] One feature I miss in the LPC81x range of MCU is a full ADC. There is however a comparitor which can be used with a voltage ladder to make crude voltage measurements. I use this for battery voltage measurement (Vcc thru voltage ladder on one comparitor input, and the built in 0.9V voltage reference on the other). In my tests it can detect low battery voltage condition, but due to the coarse resolution I get a warning only about a hour before the voltage drops below the cutoff threshold.

[5] https://github.com/jdesbonnet/RFMxx_LPC812

[6] https://github.com/jdesbonnet/RFM69_LPC812_firmware

Updates:

11 Feb 2015: Added link to firmware repository on GitHub.



Use Nokia 5110 with Arduino

$
0
0

In Tutorial 4, we learnt interfacing an HD44780-based LCD to a chipKIT board for displaying alphanumeric output. Today, we will see how to connect a NOKIA 5110 graphical LCD (used in Nokia 5110 cell phones), which is a 84×48 pixel monochrome display of about 1.5″ diagonal in size. The display can be used for graphics, text, and bitmaps.

T7_Title

Theory

Nokia 5110 LCD was used in Nokia’s popular 5110 and 3310 model cell phones. It is a 48×84 pixels matrix LCD driven by the low-power PCD8544 controller chip. It is powered by 3.3V and includes on-chip generation of LCD supply and bias voltages, thus requiring minimum external components for its operation. The PCD8544 receives display data and commands from a microcontroller through a serial bus interface. There are multiple Nokia 5110 LCD modules in the market; they all come pre-mounted on a PCB and look similar but the pin arrangements might be different in some modules. This is a very popular display among the Arduino community because of its low cost (~$3 on eBay) and simplicity to use with easily available open-source libraries. The LCD requires 5 I/O pins for full control. The pins available in almost every Nokia 5110 LCD modules are listed below:

  1. RST: Display reset input
  2. CE: Chip enable input
  3. DC: Data or Command select signal
  4. DIN: Serial data input
  5. CLK: Clock input
  6. VCC: 3.3V power supply
  7. EL: Backlight LED anode (connect to 3.3V)
  8. GND: Power supply ground

Nokia 5510 LCD module

Circuit Setup

For this experiment, we are using chipKIT Uno32 pins 8 through 12 to drive the data and signal lines of the Nokia 5110 LCD module. The connections are made as follows:

chipKIT Nokia 5110 LCD connections

We will also connect a DHT22 temperature and humidity sensor to the chipKIT Uno32 to add more fun to our experiment. DHT22 is a low-cost temperature and humidity sensor that provides calibrated digital outputs through a single wire digital interface. The following figure shows the pin diagrams of the DHT22 sensor.

DHT22 pin diagram

A pull-up resistor (usually 4.7K) must be connected between the Data and VCC pins. In our experiment, the sensor data pin is connected to pin 7 of chipKIT Uno32, while the sensor is powered through the 3.3V supply pin on the chipKIT Uno32 board. The complete setup of this experiment is shown below.

T7_Setup

Writing sketch

We will need to install two libraries for developing the firmware for this experiment. The first library required is the standard Arduino DHT22 library, which is modified by Trevor van der Linden to make it work with chipKIT platform. The second one is Nokia 5110 LCD library for chipKIT from Rinky-Dink Electronics. There are two versions of the LCD libraries: LCD5110_Basic, which supports texts, and LCD5110_Graph, which supports text, graph, and bitmaps. Download and install these libraries to your mpide/libraries/ folder using the following download links.

Download DHT22 Library

Download LCD5110_Basic

Download LCD5110_Graph

The chipKIT program for this experiment can be downloaded from the following link:

Download chipKIT Sketch

Output

After uploading the chipKIT firmware, the temperature and humidity measurements are displayed on the LCD screen as shown below. The values are refreshed every 5 seconds.

T7_OP2

The LCD5110_Graph library comes with some examples of graphical and bitmap displays, which can be found inside the examples sub-folder and accessed easily through MPIDE environment from File->Examples navigation menu as shown below:

Accessing examples from MPIDE

I would highly recommend to test and run these examples to get more familiar with the LCD5110 libraries. Simply upload these examples one by one to the Uno32 board without making any changes to the current circuit setup and see the action on the LCD screen.

Running sine wave, chipKIT logo, and Pacman examples

– See more at: http://embedded-lab.com/blog/chipkit-nokia-5110-lcd-example/#sthash.FDpyI8vU.dpuf


Feeding power to Arduino: the ultimate guide

$
0
0

Feeding power to Arduino: the ultimate guide

By on July 9, 2015

imm di copert

 

Let’s deal with the problems of the various powering modes for the most famous Arduino boards, in order to overcome doubts users may have and to provide useful advices.

When you want to use an Arduino board in stand-alone mode, the first problem to face is the one of how to power it, once it is disconnected from the computer’s USB port. Unfortunately, a faulty knowledge of the theme of powering sometimes leads people to make unforgivable mistakes, since the first result is often that of seeing the board go up in smoke and almost always irremediably, since from that moment it will not work any more.

In the premise it is good to point out that the article will deal with the powering modes of the Arduino boards operating at 5 V (UNO, MEGA, Duemilanove); a short, specific note will be dedicated to Arduino YÚN, that is still a 5 V board, but with features that are different from the other ones.

 

THE EXTERNAL POWER SOURCES

Basically, in addition to the computer’s USB port, the external power sources for Arduino are: linear and switching power supplies, or having a specific USB output (that most likely is of the switching kind) and batteries of various types.

 

THE POWER SUPPLIES

Amongst the many mistakes that are made, there is surely the one of recycling power supplies kept in a drawer, and by treating them as if they were all the same. Let’s start immediately by making it clear that those of the alternating current kind have to be absolutely excluded (they were used a lot by the analog modems of some years ago). In the figure  we can see the comparison between the two power supplies that are very similar, from a physical point of view: one operates on alternating current (AC) and the other one on direct current (DC).

 

Fig1

Comparison between power supplies operating on AC and DC

 

As it can be noticed from the symbols found on the respective tags, it is quite simple to distinguish the two models, even though they are physically similar.

In the alternating current model, shown on the right side of the figure, the line with the indications concerning the output says: AC 12 V 500mA 6VA, that respectively represent: alternating current, maximum output load and power, expressed in VA (that can always be obtained by means of the P = V*I formula). In some cases, in the place of the AC abbreviation, the symbol “~” may be found, and it still means “alternating current”.

On the left, on the contrary, the direct current model, in the line with the output values shows in an equally clear way +5 V 2A, moreover the symbol “═” graphically points to the direct current; finally, in these power supplies, the voltage polarity is always indicated on the output JACK; in this case the graphics represented on the tag indicates that the positive pole (+) is connected to the central part of the jack while the negative pole (-) is connected to the external part. We may still notice the presence of the “~” symbol on the tag, but it is clearly referred to the power supply input that, obviously, must be connected to the alternating current network.

In the course of this article we will talk about direct current only, having already clearly ruled out the alternating one for our purposes. Basically, the power supplies can be divided in three categories:

Unregulated linear power supplies: an unregulated linear power supply always takes into account an AC transformer converting from 230 Vac to a definitely lower value (usually from 3 to 24 Vac), a diode bridge rectifier (that has the task of converting the alternating current into direct current) and an electrolytic capacitor for filter and levelling. There are the so-called “multiple winding” models that have a transformer with a single primary winding for 230 Vac and many different secondary windings, and it is capable of supplying different alternating current voltages that, by means of a commutator, are connected (only one per time) to the diode bridge and to the capacitor, and therefore to the output. By measuring the behaviour of an unregulated power supply (regardless of the fact it is a single or multiple winding model) with a normal multimeter, it is possible to immediately notice how the voltage, in the absence of load, may be definitely higher than the nominal one, while in the presence of a load it proportionally decreases, depending on the current draw of the last one, decreasing even under the level of the nominal voltage. These power supplies do not offer any reliability and are often even harmful for the machineries that, if absorbing little, are powered at voltages that are much higher than the required ones. Consequently, they are absolutely to be avoided!

 

Fig2

Unregulated linear power supply

 

Regulated linear power supplies: this kind of power supply is characterized by the presence of further electronic components, in comparison with unregulated models, such as a voltage regulator and other capacitors with filter and anti-self-oscillating functions. In the greatest majority of cases they are single voltage tools, and very reliable ones, of dimensions that are proportional to the deliverable power; the voltage is very stable (typical variations of ±0,1V in respect to the nominal value), regardless of the current (always within the limits of the nominal value). In addition to an excellent stability, they have a very low ripple value (the residual variation of alternating current over direct current), but their performance is quite low (between 40% and 60%) since much power is dissipated by the regulator that, for this reason, may require a dissipation system that can even be quite bulky. The power dissipation is directly proportional both to the drop-out (the difference between input voltage at the regulator and output voltage from the same) and to the deliverable power. Moreover, the greater is the dissipated power, the greater is the temperature reached by the regulator’s case and, consequently, the lesser is the deliverable power. For such reasons the input voltage should always have a slightly higher value than the nominal one of the regulator. These power supplies are ideal for applications whose noise (ripple or high frequency) may prove harmful to the proper functioning of the circuit, typically when dealing with very low voltages. In general, they require an input voltage corresponding to the one of the electric network (230 Vac) or with quite a narrow range (220-240 Vac), moreover they are quite bulky.

 

Fig3

Regulated linear power supply

 

Switching power supplies: this last family of power supplies is the most recent, from a technological point of view; it is based on a high frequency work system and it is capable of regulating the output voltage at a value that is lower (step-down) than the input one (as in the case of the kind seen before), or at a higher value (step-up). The design of these systems is much more complex than the linear ones, but recently many integrated circuits have been put on the market, and with the help of a few external components, whose values can be calculated with the help of the data-sheet, and that make their creation quite easy. The dimensions are very limited, because of the high efficiency of such technology (80-90%) and even the stabilization is excellent. On the other hand, in respect to the regulated linear models, these power supplies have high ripple levels in addition to high frequency noise, which makes them not suitable to power circuits that suffer from such residual presences on powering. In general, they operate with a wide range of input voltages (100-240 Vac) and have dimensions that are definitely much smaller than their counterpart of the linear kind.

 

Fig4

Switching power supply

 

A particular type of switching power supplies is the one of mobile phone chargers; in general their usage is inadvisable since they have been designed for the exclusive purpose of recharging the battery, and thus often paying little attention to the noise filtering. Some models even incorporate the control system of the battery charge power, for example the ones for LiPo or Li-Ion batteries, thus making them totally unsuitable to power circuits that are different from the ones of a mobile phone.

 

THE BATTERIES

It is important to deal briefly with the problems connected with battery powering, since the need to make a circuit independent from the home electric network is not rarely felt. When deciding to resort to battery powering, the ratios between their capacity (usually expressed in mAh) and the power required by the Arduino board and the peripheral circuitry connected to it are often neglected, thus leading to results that are often disappointing (autonomy is very low or the system does not turn on at all).

In figure we represented an overview of the most commonly used battery types.

 

Fig5

Batteries Overview

 

Since a single battery cannot always satisfy all circuital needs, because of the low voltage value and/or low capacity, it becomes important to understand the series and parallel mechanism, that is to say, the ways with which two batteries may be connected between them to increase the said values. As a premise it must be very clear that all the batteries that will create a “pack” must be absolutely identical and possibly coming from the same batch; in the case of alkaline batteries they must strictly be new, in the case of rechargeable batteries all of them must be either fully charged or discharged.

Identical batteries, connected in parallel (all the positive poles between them and all the negative poles between them, see in figure) keep the same nominal voltage of a single one and sum up the capacities: e. g. four 1,5 V 200 mAh alkaline batteries connected in parallel make up a 1,5 V battery with a capacity that is equal to the one of a single battery multiplied by four (800 mAh). One resorts to this system when the voltage of the single battery is enough to power the circuit but a greater autonomy is needed.

 

Fig6

 Battery Pack in parallel

 

Identical batteries, connected in series between them (the negative pole of the first one goes to the positive pole of the second one, and so on), keep the capacity of the single battery and sum up the voltages: e. g. five 1,2 V 2000 mAh NiMh batteries, connected in series, make up a 6 V 2000 mAh pack. The connection in series is used when the single battery has a voltage that is too low and is unable to power the circuit; in fact in the specific example, with a single 1,2 V battery we could never power Arduino, and not even with 2, 3, or 4 batteries in series, since we would obtain 2,4 – 3,6 – 4,8 V respectively, and these wouldn’t still be enough for the purpose; on the other hand the fifth battery enables us to reach a 6 V tension that can be applied, for example, to the Vin pin, as we will see.

 

Fig7

Battery Pack in series

 

Of course, it is possible to combine the two types of packs, when in need to increase both the voltage and the current. For example, by connecting in parallel two packs already connected “in series” and made up by five 6 V 2000 mAh NiMh batteries (the pack described just a while ago), it is possible to obtain a 6 V 4000 mAh pack.

Hermetic Lead-Acid batteries are packs made up by 2 V elements that are connected in series; usually they are used alone, since they exist in various “sizes” as for voltage and capacity, but they still can be used in series or in parallel.

It is quite a complex thing to create Li-Ion or LiPo battery packs (the single cells must be “balanced”) therefore it is definitely more convenient to resort to commercial products. There are, however, specific battery chargers for these models’ packs, since each cell of the pack must be charged individually.

 

Fig8

Battery charger for LiPo/Li-Ion batteries

 

It is necessary to keep into account that the recharge system used by LiPo/Li-Ion batteries is very different from the one used by NiMh or hermetic Lead-acid batteries, thus you have to read up correctly before adopting any kind of batteries for your own project.

As regards autonomy, the calculation is quite a simple one, even though the thing gets complicated in the cases of “multi voltage”; in general it is enough to operate a division between the global capacity of the battery (expressed in mAh) and the circuit power consumption (expressed in mA) so to obtain the autonomy time (expressed in hours).

For example, an hermetic 12 V 2400 mAh Lead-acid battery, powering a circuit requiring 12 V 300 mA overall, guarantees a maximum autonomy of 2400/300=8 h(ours).

LiPo/Li-Ion batteries have the peculiarity to be able to deliver, even if for a very short time, current for values that are definitely greater than their nominal value, therefore they are very used in fields that require high inrush currents. On the other hand, they do not lend themselves for the creation of the so called “buffer” applications, that is to say, when a circuit is normally powered by the electric network and the batteries, constantly kept under charge, are used only when the power goes out (for example, in domotic installations), since they would get damaged in a very short time.

In these cases, the most suitable batteries are Lead-Acid ones, while NiMh or, worse, the older NiCd, suffer from the so called memory effect, thus it is better to use them until they are fully discharged to recharge them again.

For the usage as buffer, the Lead-acid batteries are definitely advisable, since they can be left constantly under charge, thus lending themselves to the task.

There are however recharge control circuits, very sophisticated ones, that in some cases allow some exceptions to what has been stated above.

 

THE INPUTS FOR POWERING

Now that we have quite a clear idea of the possible external power sources, we may see how to apply them to Arduino. Everything we will describe in this paragraph can be applied to all the kind of sources previously described, thus both power supplies and batteries. We point out again the need to pay maximum attention to the polarities: it is very important to connect properly the positive and the negative poles to the Arduino board, otherwise there is the risk to see nothing work or even to make irreparable damages. In fact, while in some cases there are some intrinsic protections on the board, in other cases the polarity inversion might cause immediate damages!

Arduino has four possible powering inputs:

 

Fig9

Arduino’s powering inputs

 

1 – USB Port: 5 V have to reach this socket (different voltages are not allowed, absolutely!), coming from a computer’s USB port, or from any power supply that is provided with a USB port (in general, they are small size power supplies, suitable to power devices that are provided with a USB cable). If the powering comes from a computer, there is a current limitation of 250 mA or 500 mA, depending on the USB port of the said computer; if on the other hand you are using an external power supply, the maximum output current (regardless of the one guaranteed by the same power supply, that in general is a maximum of 1 A or 2 A) is anyway limited to 500 mA by the PTC self-resettable protection fuse.

2 – JAPAN JACK socket: an external source (a power supply, usually) must be connected to this socket, with the positive pole going to the central part of the jack, and the value must be ranging between 6 V and 20 V, even though the range recommended by the manufacturer is 7÷12 V, thus it is not advisable to use voltages that are lower than 7 V or greater than 12 V, if not in the case of a real need; 6 V may not guarantee a proper stabilization on the part of the regulator, it is in fact needed to consider the voltage fall of the protection diode, placed in series at the regulator’s input (whose purpose is to preserve the board from destruction in the case of polarity inversion on the jack); while values above 12 V would create an excessively high drop-out (an electric potential difference between the regulator’s input and output) that would cause a pointless overheating of the regulator, even with low levels of current draw.

3 – Vin socket: this socket has a dual function.

3a – input for external powering, not protected by polarity inversions: in fact the connection goes directly to the regulator’s input and below the JACK socket’s diode; of course no voltage must be applied to the jack socket, otherwise dangerous conflicts might arise;

3b: output from which to draw the voltage applied to the JACK socket, detracting the protection diode’s fall. It might prove useful to power small loads, requiring a voltage higher than 5 V and equal to the one applied to the JACK socket (always considering the diode’s voltage fall).

In both cases the voltage negative pole can be found on the board’s GND sockets.

4 – 5 V socket: it is directly connected to the regulator’s output, thus the 5 V to power external loads to Arduino can be drawn from it. In the case voltages are not applied to the USB Port or to the JACK socket, the 5 V socket can be even used to power Arduino directly, if having an external stabilized 5 V source. One has to consider that, in general, regulators do not like voltages being applied to their output, but in this particular case this situation turns out to happen even when powering Arduino from the USB port, therefore we may assume that the designers judged this problem as harmless. Even in this case there is no form of protection, since both the diode and the PTC fuse are found above this socket and thus they do not have any active function. As in the case of the Vin socket, the voltage negative pole can be found on the board’s GND sockets.

NOTE: regardless of the input used, Arduino has a 3.3 V output socket to power loads operating at this voltage; in fact a second regulator, right for the purpose of generating 3.3 V, is directly connected to the 5 V. This socket cannot be used as input.

 

CONFLICTS MANAGEMENT

Arduino is provided with a comparison circuit that controls a type P MOSFET; if a tension is found on Vin (powering from the JACK or from the Vin socket), the MOSFET is interdicted and the possible presence of voltage coming from the USB port is ignored; in the opposite case, the MOSFET will connect the USB port’s 5 V to the 5 V socket, hence below the regulator, thus powering Arduino.

 

Fig10

Management circuit of the power conflicts

 

Therefore it is clear that if you apply the voltage to the USB port and an external source to the JACK socket at the same time, it will be this last one to power the circuit, while the USB connection will keep working for the data exchange with the computer and no longer as a power source. We remind that in both cases the 5 V socket cannot be used as input, but only as output.

 

THE CHOICE OF THE INPUT

Having now a clearer picture on the subject of the power sources and the various inputs offered by Arduino, it is necessary to decide which of the latter should be used for each specific project. The choice must obviously be made on the basis of the source available, but also on the basis of the external peripherals to be powered.

It must be noticed that, as regards the current delivered, it is important that the source is capable of making it available for as much as needed by the maximum load, to be increased by about 20%, in order to avoid that the said source works at the limits; it then has no importance if the increase is by 50% or even 100% greater; in fact if the power supply is capable of delivering 2 A and the load required is only 100 mA (thus 20 times less), there is no risk to damage things, since the residual power quantity will simply remain “available”.

On the other hand, it is extremely dangerous not to take the voltage into account, since it has never to exceed the limits provided or allowed; for example for no reason it will be possible to apply voltages exceeding the 5 V socket even by a single Volt, since the board’s integrated circuits would burn immediately!

1 – USB Port: this one is handy for experimenting with small loads, requiring 5 V, since it enables the dual function of powering and programming the board; the power limit imposed by the PTC fuse is 500 mA, and actually, these components tolerate up to almost twice the value before a protective intervention, but it is better to consider the nominal value; the polarity on the USB socket is a standard one and thus does not cause problems;

 

Fig11

Powering Arduino by means of USB Port

 

2 – JAPAN JACK Port: in general, one resorts to this port to increase the power availability on the 5 V (within the limits allowed by the regulator) and/or to have available a voltage greater than 5 V, in order to power external loads. For example, if you have to power a 12 V relay, Arduino’s pin alone is not enough, but it can be used to pilot a transistor that will bring, as a conductor, the 12 V needed by the relay. In this case a 12-12,5 V voltage is applied to the JACK socket, Arduino’s board is powered by the regulator’s 5 V and from the Vin socket it is possible to draw 12 V to send to the relay (by means of an appropriate circuital configuration); the positive pole must be applied to the JACK’s central pin, the negative pole to the external one;

 

Fig12

Powering Arduino by means of a JAPAN JACK socket

 

3 – Vin socket: as said before, this one can be useful as input if an external voltage is needed and you only have 6 V available, in fact the Vin socket bypasses the protection diode and the regulator may operate properly; or it may be useful to draw the voltage coming from the JACK socket; considering the fact that the Vin socket is unprotected, its usage by the unexperienced is definitely not advised. The positive pole must be connected to the Vin socket, the negative one to the GND. In figure you can see Arduino powered via the Vin socket on the left, while on the right it is powered by means of the JAPAN JACK socket and from the Vin the voltage to light a LED is drawn.

 

Fig13

The Vin socket used as input or as output

 

4 – 5 V socket: even in this case it should be preferable to resort to drawing rather than to inputing voltage, given the enormous risks that are taken when missing protections; one of the possible situations in which this socket comes in handy is the one of having a stabilized 5 V power source but without a USB jack; as previously seen it is necessary to apply at least 7 V to the JAPAN JACK socket and at least 6 V to the Vin socket, thus this socket is the only one capable of accepting 5 V exactly. Going back to the relay example, if having the availability of a model operating at 5 V, but that requires a greater power than the one delivered by one of Arduino’s pins (that cannot exceed 30-35 mA), even here the problem would be solved very well with a transistor and by drawing 5 V from this socket. The positive pole must be connected to the 5 V socket, the negative to the GND.

 

Fig14

The 5 V socket used as input or as output

THE LIMITS OF THE CURRENT

Let’s start by remembering that you cannot pretend to power a load requiring a certain current, without the source being capable of delivering it, and that any load draws the power it needs and not the available one. Let’s see some examples, assuming that Arduino will draw the maximum possible (200 mA), the rest is then absorbed by the external components:

a – Global current consumption of 400 mA; in this case it is possible to power everything via USB, on the condition that the computer’s port (or the power supply with USB output, used as its substitute) is capable of delivering all the 500 mA considered as maximum limit;

b – Global current consumption of 600 mA; in this case it is NOT possible to power the circuit via USB since we saw that the limit set by the PTC protection fuse is of about 500 mA; we have then to resort to an external source applied to the JACK port, one that is capable of guaranteeing a current that is greater than the one required by at least 20-30%, thus for a total of at least 600-700 mA, and as stated before the exceeding current available is not used. The voltage for the peripherals can be drawn from the 5 V pin. As already seen, however, the USB connection may be kept for the programming of the micro or for the usage of the serial monitor.

c – Let’s see the case in which the total drawing is 1A; even in this case we have to resort to an external voltage to be applied to the JACK, but as we will see in the next paragraph we are operating at the extreme limit of the regulator, thus it will be needed to separate Arduino’s powering from the one of the external loads.

In the case in which there are no peripherals requiring a voltage greater than 5 V, for example 12 V, it is needed to resort to an external power supply, applied to the JACK socket, but to understand how to draw the two voltages one must always assess the currents drawn by Arduino and the 5 V and 12 V loads. Let’s see some examples:

d – Let’s see the case of Arduino (200 mA), with 5 V (50 mA) peripherals and 12 V (300 mA) peripherals; by applying a 12 V power supply with at least 1 A maximum current, the limits of the regulator (that we will see in the next paragraph) enable us to power Arduino and its 5 V and the 5 V peripherals; as regards the 12 V peripherals, on the other hand we could draw that voltage from the Vin pin;

e – Let’s see the case of Arduino (200 mA), with 5 V (300 mA) peripherals and 12 V(1A) peripherals; by applying a 12 V power supply with at least 2 A maximum current, the limits of the regulator (that we will see in the next paragraph) will impose to power Arduino alone with its 5 V, while it will not be possible to use the Vin pin (see following NOTE), at this point it a different solution should be found.

NOTE: let’s consider another factor, this time concerning the Vin pin; apparently there should not be limits of deliverable current, in addition to the one imposed by the applied power supply; however all the current will have to flow within the protection diode, that is anyway quite sturdy, but de facto one has to consider that the copper track, that connects the regulator’s input to the Vin pin placed on Arduino’s POWER header, is not very thick and consequently may not endure high currents, as it would risk burning.

 

THE REGULATOR’S LIMITS

We now have to face the problem of the power the regulator has to dissipate; by reading the specifications on the data-sheet  of the NCP1117ST50T3G regulator in the SOT-223 case (the one used on Arduino UNO r3) it can be seen that the maximum operating temperature is 150°C (being a “maximum rating” value one should keep himself at about 20% under it, thus let’s consider 120°C); it can also be read that the regulator reaches a temperature of 67°C for each Watt to dissipate, thus we can reasonably consider a maximum power to be dissipated of about 2W (actually the formula on the data-sheet calculates 1,87W at 25°C). We have already seen how to calculate the power by means of formulae; by opportunely moving the terms we can calculate the maximum deliverable power: for example I = W / (Vin-Vout). Let’s see some examples:

– 12 V Power Supply: I = 2 / (12-5) = 2 / 7 = 285mA

– 9V Power Supply: I = 2 / (9-5) = 2/4 = 500mA

– 7 V Power Supply: I = 2 / (7-5) = 2/2 = 1A

These calculations do not take into account the fall on the input diode, but are however based on a power that is greater than the advised one, thus we may consider them to be reasonable. It can be clearly inferred how it can be definitely preferable to apply the lowest power possible to the regulator.

In the previous “b” example, in which 600mA were needed, it can be well understood h now how voltages greater than 8V cannot be applied to the JACK, while in the “c” example we are definitely at the limits, even applying 7 V at the input, thus in this case we cannot think to make all the current flow through the regulator, but a different system has to be thought of; the same goes for the “e” example, while we have seen that the “d” example lends itself to the usage of a single internal power.

 

POWER SOURCES THAT ARE EXTERNAL TO ARDUINO

In the previously seen examples, we verified possibilities that go beyond the limits of the internal regulator and even of Arduino’s tracks; in these cases a possible solution is the one to create an external board that makes available a series of outputs to power both Arduino and the external peripherals operating at 5 V or other voltages (typically 9 V or 12 V).

– Let’s consider the “c” case: 5 V 1 A are needed, since 200 mA are allocated to Arduino and 800 mA to the 5 V peripherals; for example there can be a 9 V source with a deliverable power that has to be about 20-30% more, for example a 9 V 1,5 A or 2 A regulated power supply; it will be enough to create a small board with an input that is compatible with the power supply jack, below it uses a 5 V regulator (for example the classic 7805 with a TO-220 case and the typical four capacitors), whose exit will go to power the external 5 V peripherals; the 9 V from the external power supply will be brought as output as well and will be connected to a JACK pin for Arduino’s socket.

 

Fig15

High power consumption 5 V circuit plan

 

– Let’s consider the “e” case: 5 V 500 mA are needed (200 mA are allocated to Arduino and 300 mA to the 5 V peripherals), and 12 V 1 A by the 12 V peripherals; for example there can be a 12 V source with deliverable power of at least 2 A; it is enough to create a small board with an input being compatible with the power supply jack, below a 5 V regulator is used (for example the previously seen 7805), whose exit will go to power the external 5 V peripherals; the external power supply’s 12 V will be brought as output as well and split on two sockets: one to be connected to a JACK pin for Arduino’s socket and the other one to be connected to the 12 V peripherals.

 

Fig16

High consumption 5 V and 12 V circuit plan

NOTE UPON ARDUINO YÚN

In conclusion of this article, let’s leave a particular note concerning Arduino YÚN, given that, even if requiring 5 V, it has a powering system that differentiates it from all the other boards. Since it does not have a power regulator on board, it can be powered exclusively with regulated 5 V power sources:

  1. by means of its micro-USB port;
  2. by means of the Vin pin, to which we need to supply 5 V exactly, just because a power regulator below is missing.

 

Fig17

How to power Arduino YÚN

 

Finally, we have to keep in mind that, on the contrary of other Arduino boards, YÚN cannot be powered by the 5 V pin on the lateral header. In fact, as it can clearly be seen on the original electric plan (pag. 5) on the 5 V pin, Arduino YÚN has a diode (D9) that allows the current to flow only as an output.

 

From the store

Arduino YUN

Arduino UNO R3

Starter kit with Arduino UNO – Basic Level


quadcopter in one inch

$
0
0

https://hackaday.io/project/7947-quadcopter-in-one-inch

one inch flying machine
10 DOF IMU, motor drivers, and 32bit ARM CPU.
  • FAA registration?

    12/15/2015 at 02:440 commentsfully assembled with battery, the device weighs 23.5 grams.

    making it exempt from the FAA’s new registration requirements.

  • oops…

    11/13/2015 at 05:362 comments

    I have a feeling this project will require a lot of ceiling paint…

  • test flight

    11/13/2015 at 05:361 comment


Help New Board : CZ Mini STM32F103

$
0
0

Help New Board : CZ Mini STM32F103

Drakelive

Posts: 21
Joined: Fri Jun 05, 2015 10:29 am
Location: Italy

Help New Board : CZ Mini STM32F103

Postby Drakelive » Mon Jun 08, 2015 11:21 am

Hi

I bought this card from aliexpress:

UT8_2CzXipaXXagOFbXY.jpg
UT8_2CzXipaXXagOFbXY.jpg (232.48 KiB) Viewed 1174 times

I would try to use it as a demo board.
I had problems to send the .bin file. How can I run the Flash?

I have tried using the USB present on the board, but maybe I need an external programmer?

thanks
Drk

User avatar

ahull

Posts: 692
Joined: Mon Apr 27, 2015 11:04 pm
Location: Sunny Scotland
Contact:

Re: Help New Board : CZ Mini STM32F103

Postby ahull » Mon Jun 08, 2015 11:37 am

USB232 on the board looks to be connected to the Prolific Chip, so I imagine that is going to allow you to talk directly to the board. You will need to set BOOT0 and BOOT1 correctly. Alternatively, you can use an ST-Link V2 clone and the Jtag connector as per the pictures below (same pins, different board). The ST-Link V2 clones can be found on Ali Express and Ebay for a couple of dollars,

Image

Image

– Andy Hull –

victor_pv

Posts: 633
Joined: Mon Apr 27, 2015 12:12 pm

Re: Help New Board : CZ Mini STM32F103

Postby victor_pv » Mon Jun 08, 2015 12:34 pm

To continue on what Andy said, the USB-232 can be used to connect to USART1 in that board.

It you don’t have ST-Link, you can use that USB-232 port to upload bins to the board.

If you connect the jumper from boot0 to +3.3 and from boot1 to GND, the board will boot the STM ROM bootloader, which uses USART 1.
As that is connected to the USB-232 with the converter, you can now use a program in Windows to upload .bin files to the board.

The STM tool for that is called something like Bootloader Demonstrator. Search for it online, it’s on STM webpage somewhere. It is a Windows only tool as far as I know.

At that point, unless you need to use all the flash in the board (unlikely), I would upload the new bootloader that we have modified to work on generic boards. It’s in a repo in Roger’s github, and there is a link to it in the announcements forum section. (the repo is STM32duino-bootloader).

Your board seems to have 2 leds in PE2 and PE0, and Roger has compiled the bootloader for several different led ports, but I don’t see it for PE2 or PE0, so you will need to modify the source and compile it.
When I get to work I can try to download the source and modify it for you if you have problems doing that.

Once you upload the STM32duino bootloader, you can use the main port to upload sketches with the DFU bootloader, which is easier to use because it reboots the board automatically and goes in bootloader mode a few seconds on every reboot before jumping to the sketch, so you don’t need to be changing the boot0 jumper all the time.

victor_pv

Posts: 633
Joined: Mon Apr 27, 2015 12:12 pm

Re: Help New Board : CZ Mini STM32F103

Postby victor_pv » Mon Jun 08, 2015 3:15 pm

I just compiled the one attached here, give it a shot and let me know if it works.
I am at work right now so I dont have any board to test it out.
I set the led to port PE2, and the button to GPIOB11, which seems to be one of the buttons in the front of that board next to the USB connectors.
ATTACHMENTS
generic_boot20_pe2.zip
(4.89 KiB) Downloaded 43 times

Drakelive

Posts: 21
Joined: Fri Jun 05, 2015 10:29 am
Location: Italy

Re: Help New Board : CZ Mini STM32F103

Postby Drakelive » Mon Jun 08, 2015 3:40 pm

Hi Victor_pv

Tonight I control the LEDs on my card but the picture seems to me to read and PE0 PE2 and the electrical diagram provided by the Chinese seller confirms it but I want to spend a few minutes to check the accuracy.
For programming I have a USB-232 working at 3.3v but Thursday I should deliver an original ST-Link V2 bought on Ebay.
I work on Linux so I need software that run on it. I was able to program the ST Nucleo Boards in linux ( on Eclipse) by filling out a simple project in GitHub (https://github.com/texane/stlink) .
I see now that while I was writing this mail have already taken steps to compile the bootloader :-) Thanks.
I think I need to read something on the bootloader to understand how it works, how to it write and how to use it to load firmware.
As always, a step at a time

I keep you updated

Thanks
Drk

victor_pv

Posts: 633
Joined: Mon Apr 27, 2015 12:12 pm

Re: Help New Board : CZ Mini STM32F103

Postby victor_pv » Mon Jun 08, 2015 3:54 pm

This program is supposed to work with the serial bootloader in linux:
https://code.google.com/p/stm32flash/

I have not used it ever, so dont know if it works, but you can give it a shot and let us know.
Once you upload the bootloader to the board, it will work like the bootloader in the official Maple and Maple Mini boards, with the DFU protocol.

User avatar

ahull

Posts: 692
Joined: Mon Apr 27, 2015 11:04 pm
Location: Sunny Scotland
Contact:

Re: Help New Board : CZ Mini STM32F103

Postby ahull » Mon Jun 08, 2015 7:08 pm

The existing ../hardware/Arduino_STM32/tools/linux/stlink_upload option should work too.

This is what is called by the following upload methods in linux.

CODE: SELECT ALL

nucleo_f103rb.upload.tool=stlink_upload
genericSTM32F103C.menu.upload_method.STLinkMethod.upload.tool=stlink_upload
genericSTM32F103R.menu.upload_method.STLinkMethod.upload.tool=stlink_upload
genericSTM32F103V.menu.upload_method.STLinkMethod.upload.tool=stlink_upload
genericSTM32F103Z.menu.upload_method.STLinkMethod.upload.tool=stlink_upload

.. so in theory the ST-Link V2 gadget should just work if you select “genericSTM32F103Z” for the board type, and “Upload method: stlink” in the IDE and wire it as per my pictures above. If it doesn’t, give us a shout and we can go through it step by step. A number of us are using Linux, so I’m sure we can get it working.

– Andy Hull –

Drakelive

Posts: 21
Joined: Fri Jun 05, 2015 10:29 am
Location: Italy

Re: Help New Board : CZ Mini STM32F103

Postby Drakelive » Tue Jun 09, 2015 2:32 pm

Hi

I spent a bit of time to understand how it is made this card. I found this:

Led –> PE0, PE2
Button –> PB10, PB11

One of the two USB port is interfaced to Chip PL2303HX. There are also two transistor which was discussed on the forum.

BOOT1 ( PB2 )
RESET# ( NRST = pin25 )
PL2303_TXD —> USART1_RX ( PA10 )
PL2303_RXD <— USART1_TX ( PA9 )

Linux reads me ttyUSB0 and serial device when I connect the board to the computer.
The second USB port is connected to pins USB_DM ( PA11 ) and USB_DP ( PA12 )

Bootloader and Programmer

Since I have a programmer ST-Link v2 do not think I can be useful a bootloader, I can directly use the programmer using the JTAG connector.
If I understand it to be able to program the STM32 chip via external programmer I needed to connect the pin BOOT1 to Ground?
Can you confirm this?

The controller ST-Link v2 has two connectors: one JTAG and a 4-pin connector.
The JTAG is simple because the generic card STM32 I own has a dedicated JTAG connector, but for the 4 Pin how do I connect to the Board?

Drk

User avatar

Rick Kimball

Posts: 367
Joined: Tue Apr 28, 2015 1:26 am
Location: Eastern NC, US
Contact:

Re: Help New Board : CZ Mini STM32F103

Postby Rick Kimball » Tue Jun 09, 2015 2:46 pm

Drakelive wrote:The controller ST-Link v2 has two connectors: one JTAG and a 4-pin connector.
The JTAG is simple because the generic card STM32 I own has a dedicated JTAG connector, but for the 4 Pin how do I connect to the Board?

Check to see if the 4 pins are GND/SWDIO/SWCLK/VCC

The USB_DP, does that have a pull up resistor? Or is there a transistor circuit that lets you disconnect?

-rick

User avatar

ahull

Posts: 692
Joined: Mon Apr 27, 2015 11:04 pm
Location: Sunny Scotland
Contact:

Re: Help New Board : CZ Mini STM32F103

Postby ahull » Tue Jun 09, 2015 10:21 pm

Drakelive wrote:
Since I have a programmer ST-Link v2 do not think I can be useful a bootloader, I can directly use the programmer using the JTAG connector.
If I understand it to be able to program the STM32 chip via external programmer I needed to connect the pin BOOT1 to Ground?
Can you confirm this?

Yes, I have Boot 0 and Boot 1 both tied to ground.

The controller ST-Link v2 has two connectors: one JTAG and a 4-pin connector.
The JTAG is simple because the generic card STM32 I own has a dedicated JTAG connector, but for the 4 Pin how do I connect to the Board?

Drk

What are the pin names on your “Jtag” and “4 pin” connectors?

Image
This might be a better picture of how I have things connected. I am only using 4 wires (SWDIO,GND,SWCLK and 3v3) as you can see from this picture and the previous ones.

– Andy Hull –

Help New Board : CZ Mini STM32F103

Drakelive

Posts: 21
Joined: Fri Jun 05, 2015 10:29 am
Location: Italy

Re: Help New Board : CZ Mini STM32F103

Postby Drakelive » Tue Jun 16, 2015 11:30 am

Hi

In the WE finally I put my hands on the controller ST-Link V2 delivered by the postman.
As a first test I used the classic Blik sckech. I only had to change the LED pin ( PE2 )
Board (CZ Mini STM32F103) and programmer, they were connected through the JTAG port.
BOOT0 and BOOT1 set on the ground.
I Compiled and binary Flashing directly from Arduino IDE.
Everything worked in the first test. No problems found. The skech works perfectly !!!!!
There was no need to change Jumper for BOOT0 and BOOT1.

As a first test I chose not to install the Bootloader

I’m really happy and super excited. Now I have to go deeper with the study.

Thank you all for your support.

Drk

User avatar

ahull

Posts: 692
Joined: Mon Apr 27, 2015 11:04 pm
Location: Sunny Scotland
Contact:

Re: Help New Board : CZ Mini STM32F103

Postby ahull » Tue Jun 16, 2015 12:37 pm

Good to see it worked first time. :D
– Andy Hull –
User avatar

RogerClark

Posts: 2423
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: Help New Board : CZ Mini STM32F103

Postby RogerClark » Tue Jul 07, 2015 3:56 am

@Drakelive

The Bootloader is worth installing, however I’ve not specifically compiled a version for a board with the LED on PE2
Annoyingly there is no standardisation for which LED these boards use.

I will try to create make file target / config for a generic board with LED on PE2

I’ve just created a bootloader version for that board (so it flashes the correct LED).

https://github.com/rogerclarkmelbourne/ … 20_pe2.bin

When you feel like installing the bootloader let me know how you get on.

BTW. On windows you need to install a driver (see driver/win/install.bat ) On Linux there is a script you need to run (install.sh)
On Mac no other installation should be required.
See https://www.youtube.com/watch?v=0jdJp3TQuJY

Note, If it doesnt look like the bootloader is working, I could have screwed up the config, as I don’t have a board to test it on (but I can have a go testing on another one of my boards by attaching an external LED)

Cheers

Roger


CZ miniSTM32F103ZET6-EK单片机系统版使用心得

$
0
0

CZ miniSTM32F103ZET6-EK单片机系统版使用心得

2013-09-22 23:59:07|  分类: 单片机 |  标签:stm32f103zet6  |举报|字号 订阅

CZ miniSTM32F103ZET6-EK单片机系统版使用心得 - Avocado - Gekkos Glory
购买地址:
stm32 ZET6引脚定义

http://wenku.baidu.com/view/eab3831cfad6195f312ba643.html

20130922 板上的LED灯:
板上的LED灯对应的端口是PE2/pin1        PE0/pin141
20130922 jlink连接速度约有300k,很快!

20130922 sd卡槽带自锁的

20130922 usb转串口芯片是pl2303
20130923 板上面的sd卡接口是接在sdio接口上面的,不是spi接口 pin98 99 111 112 113 116

20130923 板上面的串口转usb是接在usart1上的 pin101 102

20130923 板上面的按键对应k1/pin69/pb10(按下拉低)     k2/pin70/pb11(按下拉低)    k3/pin25/nrst(3.3v nor.)

20130923 板上面的usb对应pin103 104 usbdp usbdm

20140120 sd卡接口好像不支持4bit模式。我有一张垃圾2g kingstone一次只能读取4个字。16g和8g的sdhc则可以一次读512字节。18mhz的sdio速度
这块开发板是哪家公司的产品啊?   博主可否把这款单片机的原理图和教程发给我啊?我现在就在学32,但苦于没有任何教程和原理图啊啊啊啊!完全不会呀!
2015-03-24 05:09
博主可否把这款单片机的原理图和教程发给我啊?我现在就在学这款单片机,但苦于没有任何教程和原理图啊啊啊啊!完全不会呀!
2015-03-24 05:09
我邮箱是1205424945@qq.com

刘仲敬:诸神之战 — 世界秩序与现代中国

$
0
0

刘仲敬:诸神之战 — 世界秩序与现代中国

2016年1月21日

“国家”是什么?“主权”是什么?是“自古以来”就存在的,还是在历史中建构起来的?一百年前的历史决断如何影响今人的命运?我们又该如何认识自己身处的位置?阿姨在2015年12月19日由冬川豆与蛇口沙龙联合举办的讲座中深入浅出地剖析了这一系列问题。讲座录音整理稿约六万字,由冬川豆精校、注释、配图及独家发布。

(一)

在高度多元的环境中,创新才容易产生。欧洲封建时代高度自由和开放的网络结构孕育了近代世界,可后来亚洲人模仿欧洲的时候,看到的都是它的果实,而不是看它的树根。

我们首先要清楚,中国这个“国”的概念是怎么回事。因为汉字有它自己先天的弱点,有很多问题其实是由汉字的特点和翻译的问题造成的。比如说“国家”这个词,翻译成“国家”这两个字,其实本身就是很有问题的。因为,比如说在欧洲语言中,同样的词有好几个,很明显是几种不同的含义,但是翻译成汉语的话,那就全都变成了“国家”这一个词或者“国”这一个词。因此仅仅是由于翻译的问题就造成了无数的混乱。所以我们先要梳理一下,“国”这个词,这个方块字,到底是什么意思。

“国”这个词最先出现在周代。你从方块字造字的规律就可以看出,什么是“國”呢,它的外面是一圈城墙,里面是一个代表武器的词。那么你从方块字的造字规律就可以看出,什么叫做“国”,那就是,一个有城墙的武装堡垒,这就叫做“国”。按照当时的规矩,就是说是,“有国”就是城墙里面,“国”之外叫做“野”,“野”就是田野之野,就是城墙以外的地方。“诸侯有国”,意思就是说是,你如果有了一个设防的武装堡垒,你就是诸侯了;没有这个武装堡垒,那你就不成其为诸侯。

你只要对照一下世界历史,你就可以看出这个封建主义的原理,它非常接近于西欧的封建原理。方块字的“国”这个词,最适当的对应语就是欧洲封建制度下的城堡。一个贵族为什么是贵族呢?因为他是武装阶级,他是有城堡的。大贵族有大城堡,小贵族有小城堡。城堡可以保护当地居民,在发生战争的时候,可以作为军事要塞来用。有城堡才能叫贵族,没有城堡就不能叫做贵族。东周时期的“国”也就是这个概念。“天下万国”是什么意思?就是说,我们所知的这个世界上有很多不同的城堡,有城堡的就是诸侯,大的诸侯有很多城堡,小的诸侯至少要有一个城堡,完全没有城堡的人那就不具备有参加有效政治活动的资格了。

那么什么叫做“中国”呢?位于文明中心地带的这个设防城堡就叫做“中国”。一般来说,周汉之际所谓的“中国”就是指的是洛阳城。因为洛阳在地理上讲是位于东亚地区的一个中心,它跟其他各地的距离基本上是等距离。所以当时的人如果说“中国”这个词,那就是指的洛阳城。比如说周人在建立了洛阳以后就宣布说,我已经做了中国的主人,向上天祭祀。什么叫“做了中国的主人”?就是说他已经在洛阳这个地方扎下来了,这就是“做了中国的主人”的意思。“国”以外那就是“野”,“野”就是没有设防城堡的地方。没有设防城堡的地方,那么是很容易被人征服的,在战时没有办法隐蔽,所以在政治上,要么是没有发言权,要么是发言权非常次要。这就是当时所谓的“国”的概念。

我们现在所谓的“中国”这个概念,跟这个有两千多年历史的方块字的“国”的概念是截然不同的。它对应于英语中间的nation这个词,意思就是民族国家。民族国家的产生是非常晚近的事情,即使是在欧洲也是十九世纪才有,十九世纪以前是没有这个东西。欧洲十九世纪的观念,随着世界体系的扩张普及到全世界各地。在大清这一块,大家用一种类似托古改制的方法,从汉语中原有的词去寻找类似的词,就用中国古籍中原有的“国”这个词来翻译nation这个词。但是必须说,这种翻译做法是不好的,它造成了极大的概念混乱。我刚才之所以要费时间讲这么多话,其实就是为了理清原先造成的概念混乱。如果我现在是用英语或者其他欧洲语言讲的话,刚才这些话纯粹是一点没有必要,你只要用nation这个词就可以看得清楚了,它绝对不会是指的设防城堡或者是其他什么概念。

我们就要看一看nation这个概念在欧洲是怎么来的。欧洲的国际体系也就是从封建体系开始的。它是多层次的,也就是说,是不同等级、但是边界并不明确的各个领主之间的多层次网络。这个网络之间是不存在边界概念的,它们由各式各样的契约关系组成。比如说假定苏格兰东海岸有一个岛,岛上有一批渔民,那么他肯定有很多种不同的封建关系。例如,他多半会向苏格兰国王或者挪威国王纳贡要求保护,因此是这两个国王的封臣;同时他还可能是某几个强有力的伯爵,比如说是海岸伯爵或者是麦克唐纳家族的附庸。在苏格兰高地的历史中,为了争夺海湾伯爵或海岸伯爵这个头衔,引起了很多大家族的长期斗争。同时,该地居民是基督徒,一般来说他们也有自己的教区,而这些教区,无论是属于谁的,它们都有自己的长上。如果是天主教教区,那么他可能有自己的主教教区,而这个主教跟上面的红衣主教、跟罗马教廷有一定的关系;如果他是长老会的,那么他跟爱丁堡的宗教会议必定有一定的关系。这个关系,政治和宗教之间多重的附庸、保护和效忠关系,形成一个极其复杂的网络。
King Arthur presides at the Round Table with all of his Knights

这个网络不是单线性的,它跟行政机关不一样。我们都知道,行政机关,照马克斯·韦伯的说法,是按照理性方法来管理,也就是说它有明确的可预期性,有明确的等级。我的上级是谁我很清楚:如果我是中尉的话,那么我的上级就是上尉;如果我是市长的话,那么我的上级就是省长,诸如此类。一级一级排下来,是一个很精致的金字塔。但是封建体系不是一个有明确上下关系的金字塔,它是一个像大脑神经元一样的一个巨大的网络,一个不断变化的网络。每一个结点,它在上下左右都有许多种不同的网络关系,而不是只有一种明确的上下关系。

像勃艮第公爵(勃艮第公国涵盖了现今法国东南部的勃艮第大区、阿尔萨斯-洛林、瑞士西部、荷兰、比利时、卢森堡等地区,曾同时是法兰西王国和德意志神圣罗马帝国的附庸,一度拥有强大实力)或者是像布列塔尼公爵(布列塔尼公国位于现今法国西北部,早期与法兰西王国关系若即若离,一度被英格兰国王通过联姻控制,后又逐渐脱离英格兰的掌控。百年战争时为英法双方都争取的对象,1532年被法国合并)这样的君侯,你很难说他到底是一个独立国家的领袖呢,还是法兰西国王的藩属呢,还是神圣罗马帝国的藩属。例如勃艮第公爵,他处在英格兰王国、法兰西王国和神圣罗马帝国之间,他在不同时期曾经向这三大君侯宣誓效忠,而且这个宣誓效忠经常是相互重叠的。这对勃艮第来说是有好处的。他可以理直气壮地说,比如说大胆查理(1433-1477,勃艮第末代君主,路易十一的童年玩伴和宿敌,曾组织贵族同盟对抗路易十一,被路易用计分化瓦解。在与瑞士人作战时战死,身死国灭)在面临路易十一(1423-1483,法兰西走向绝对主义的开路人,精明强干、诡计多端,人称“万能蜘蛛”)的压力的时候,他可以说,如果路易国王欺人太甚的话,第一,我可以去找神圣罗马皇帝(大胆查理曾请神圣罗马帝国皇帝封他为国王,差点成功),让皇帝陛下给我发一个特许状;因为皇帝的阶位高于国王,所以我可以说,你如果逼得我太紧,我勃艮第根本就不再属于法兰西王国的一部分。他还可以说,我可以把我的女性亲戚嫁给英国的爱德华国王或者是英国大贵族(实际上,大胆查理的女儿在他死后嫁给了神圣罗马帝国皇帝马克西米利安,皇帝为保护妻子的领地击退了路易十一的进犯),然后根据封建义务,调一支英国的弓箭手来守卫勃艮第城堡,要是法兰西国王把我逼得太狠的话,你要当心英国人会重新出来,英法百年战争的旧事又要重演。他还可以说,我可以组织一个公义联盟,就是说,跟布列塔尼公爵、诺曼底公爵和其他大贵族结成联盟,共同抗争法兰西国王。当然还有罗马教皇和其他各种关系。这不仅仅是勃艮第公国,所有的封建领主,他都有这样错综复杂的关系。
欧洲封建阶级关系示意图

这个关系的复杂性,比起近代的外交关系要大得多。在这种情况下,没有任何一方是享有绝对权力的,而且也没有任何一种权力的边界是始终如一、非常清晰、从来不发生变化的。法兰西国王也好,勃艮第公爵也好,还有底下的各个小贵族、小男爵也好,他们都签署了无数的私人契约关系。这些契约关系是需要随时调整的,通过战争、条约、仲裁、司法,各种方式调整。这个网络的复杂性,不仅比官僚科层制度要复杂,而且比现在的国际关系都要复杂得多。复杂的结果就是,没有任何人享有绝对权力。这是一个隐含着无限演化可能性的网络。所以近代社会从欧洲逐步的演化生成,这不是偶然的。

现在中国的读者基本上有一种误解,把果实跟种子看成是一回事,他们看到近代欧洲的繁荣、昌盛和强大,就以为那是近代欧洲民族国家的产物,然后一味地模仿民族国家产生以后的东西。殊不知民族国家,它本身就是欧洲封建制度的产物。首先是欧洲封建时代那种高度自由和开放的网络结构孕育了近代世界,然后才能产生近代世界的种种东西。可以说后来,亚洲人,包括世界上欧洲以外的其他地方,模仿欧洲的时候,看到的都是它的果实,而不是看它的树根。这个树根是什么?就是我刚才讲的,它是欧洲的封建制度。人类已知历史以来,从来没有像是欧洲封建系统这样高度多元、具有高度自发秩序特点的秩序。

马克思主义所谓的“封建制度”,例如像秦始皇以后的中国各代王朝的这种“封建”,是没有这种多元结构的。恰好相反,它的主要特点就是一元化的、高度严密的科层制度。你要在官僚制度内部产生各种结点是不可能的。所谓人臣无外交,如果我是湖广总督的话,那么我就必须首先向上服从皇帝,向下指挥武昌的知府,然后武昌的知府再向下指挥他底下的各种官员,一直到最基层的保长、里长。一个指挥一个,构成金字塔结构。

这样子的体系,一方面是没有灵活性;另一方面,更重要的是,它没有自己产生秩序的能力。科层制度的秩序资源是必须从外部输入的,它自己没有维持秩序的能力。如果没有皇帝利用全国资源去指挥它的话,这个制度马上就要倒台。它不可能像大脑的神经系统,或者像市场经济一样,在自己的演化之中不断产生出新生事物。你制造了一个科层制度以后,它只能够慢慢的崩坏。开国时期的科层制度很严密,时间长了,因为腐败的缘故,就渐渐变得不严密了,最后完全垮台,是一个退化的过程。它不可能像灵活的多元网络一样不断产生出新东西,像市场一样不断产生出新的企业,像生态系统一样不断产生出新的物种。欧洲封建制度,它像市场经济,像生态场;而东方的官僚制度,它是一个没有发展可能性的僵尸制度。一个是秩序的来源,一个是秩序的消费者,两者是截然不同的东西。近代世界,是秩序的生产者——也就是一个多元网络结构造成的。各位如果去过硅谷的话就可以明白,多元网络体系是怎样自动地不断产生新物种的。欧洲是创新的源泉,归根结底是因为它有天然的多元体系。

像后来孟德斯鸠他们说的那种三权分立,它就不是一个理论的虚拟。我们要理清楚,并不是孟德斯鸠或者后来的专家学者提出了三权分立这个概念,认为应该制造三大可能的权力机构,而是孟德斯鸠所在的那个世界上,本身就存在着几千种甚至更多种不同的权力机构。孟德斯鸠像别的知识分子一样,他看到这些不同的权力机构,觉得应该给它搞一下分类整理,他就说,这些各种不同的、千奇百怪的权力机构应该分为三大类:一类,比如说像法兰西国王,应该算是行政权力;一类像是英格兰的国会,应该算是立法权力;一类呢,像他自己任职的波尔多法院(孟德斯鸠继承伯父的封号成为男爵,并继承了伯父的波尔多高等法院庭长职务,后来他将这个官职卖掉),应该算是司法机构。其实这个分类是不严密的。我们都知道,巴黎的所谓的国会或者最高法院是兼有立法和司法职能的。而英法两国的国王,自己在行政职能之外,也兼有一部分立法职能。但是这不重要,重要的就是,“三权分立”其实不是三权分立,而是在已经成立的多元权力结构之下,把它分为三种不同的类型。它不是三种权力,而是多种权力被专家学者分成了三种类型。
三权分立示意图

但是亚洲人为什么会把它当作三种权力呢?因为亚洲原本就是高度一元化的。不要说是有几千种不同权力了,你连两种权力都没有,一切都属于皇帝。于是他自然而然地用自己的经验来想象欧洲,他就想象三权分立应该是建立起来的东西,不是总结出来的东西。三权分立既然这么好,那么我们应该把原有的权力拆成三份,搞成总统、国会和最高法院,这样我们就变成跟欧洲一样好了。这样做为什么不能成立?因为你是把这个过程给颠倒了,人家是把本来有的各种多元权力拿来做一个有效的整理,而你是根本没有这样的多元权力体系,你就想从白地里面建立出三种独立的权力,那是完全不同的两码事了。

近代以来的历史,就是欧洲产生出来的极为丰富的各种组织资源向全世界扩散的过程,其中也包括东亚。这一点不难理解,你说全世界的互联网产业怎么来的?它们都是以斯坦福大学为中心,其范围充其量不过几十万英亩的这一个微不足道的点扩散出来的。全世界所有的互联网企业,都是加利福尼亚西海岸那个弹丸之地扩散出来的,他们产生出了互联网的种种秩序,然后向全世界输出。全世界现在的互联网有几十个根,其中有十个都在美国,而且都在加州。全世界近代以来所有的秩序资源,也是按照相似的方式输出到世界的。可以说,当今世界绝大部分秩序和组织,都是来自于欧洲西北部这一小块。现在的非洲、亚洲、拉丁美洲,或者是任何地方的组织资源,最终都归属于这个地方。

我们所谓的近代化或者是现代化,它不是一个时间过程,而是一个扩展的过程。例如中国的互联网企业是谁创立的?你不能说是,我们早在《易经》的时代,伏羲就研究过互联网,《易经》就是互联网精神的一个记录——我不是开玩笑啊,有很多伟大的历史研究都是在说诸如此类的胡话的——汉代经师的研究,进一步发展了互联网的精神;宋代邵雍的河图洛书的研究,把互联网的技术推到了一个更高的水平;最后,在康熙皇帝的时代,中国的互联网研究者跟莱布尼茨对上了头,但是中国方面的研究毫无疑问比欧洲要先进得多;结果到了现代,全世界都进入了互联网时代。
“《周易》中的二进制数学”

我刚才举这个例子的意思就是说,在座的诸位所读到的历史,跟我刚才在两分钟之内临时发挥出来的历史,可靠性是一模一样的。全世界所谓的现代化研究,跟我刚才提出的这个互联网研究,基本精神是一模一样的。所有的这方面专家学者所得出的结论,跟我刚才在两分钟内发明出来的历史的可靠性,也是完全相等的。真实的互联网历史就是,它是在第二次世界大战以后,在美国的弹丸之地,由几千个头脑发热的年轻人搞出来,然后在几十年时间内扩散到全世界。虚拟的互联网历史则是,全世界各地都在一点一点地产生,最后到近代世界的时候,大家一起产生了互联网,只不过美国特别先进一点。哪一种历史更真实,我想大家心里是有数的。所谓的现代化,也有我刚才说的两种说法,就是说是:各地都在产生现代化,只是欧洲领先了一点;另一种说法就是,欧洲产生了现代化,而欧洲的现代化按照互联网扩张的方式播种到全世界。毫无疑问我是主张后一种看法的。就我看到的所有材料来看,前一种说法是一点都不靠谱的,就跟《易经》产生互联网的逻辑一样的不靠谱。

欧洲秩序的扩张波及到东亚这个地区,就产生了一个后果,就是说它产生了中国这个概念。因为大清——不能说中国了,大清、日本、韩国、越南这个儒家文化圈的士大夫首先接触到欧洲的时候,他们并不了解欧洲历史和秩序自发生长的这个逻辑。他们根据自己的想象,从这些秩序中摘取他们认为重要的那部分,然后拿回来。他们看到的最重要的地方,至少在大清和日本这方面,最重要看到的就是船坚炮利,看到英国是如此的强大和船坚炮利,而大清和日本好像就没有这么船坚炮利。于是他就想象,为什么别人有强有力的国家组织而我没有呢。于是他就发明出国家这个概念,去嫁接在欧洲刚刚出现的民族国家,然后在后来就变成一种错误的认知图景,就是说,学习欧洲的先进,引进欧洲的国家建构,国家应该如何如何建构之类的。

但是我们要明白,在1840年以后,甚至到1900年以后,欧洲向东亚输出秩序的过程,不是一个固定的目标在教你什么秩序、输出什么秩序的过程,而是欧洲本身在不断变化,因此输出是一波接一波来的。先来的输出和后来的输出是有重大差异的。像在鸦片战争刚刚开始的时候,民族国家这个概念在欧洲本身顶多也仅仅是一个想象,而不是落到实处的东西。欧洲本身还实行的是半封建性的,各种法人团体之间是有战争权力和外交权力的,所以才会有东印度公司这样的东西。

我想,大多数现在的亚洲人对东印度公司征服印度都是不大了解的,他们总是把这件事情当成英国征服印度。但是真正的历史是,英国从来没有征服印度,也从来对征服印度不感兴趣。只是东印度公司这个法人团体在印度做生意的过程中,跟当地的王公、埃米尔(伊斯兰世界中封建领主或地方军事长官的称号)之类的发生了一系列的交涉,然后有的埃米尔赖债了,东印度公司就召了一支雇佣兵去跟他打仗,然后占领了这些埃米尔的宫廷,然后埃米尔政权崩溃以后,他因为找不到收钱的对象,所以就不得不在印度住下来了,然后莫名其妙地就变成“一个公司建立一个帝国”的怪事。而英国政府在这方面,实际上它什么也没有做。英国政府统治印度,是印度大叛乱、东印度公司解散以后的事情(1857年印度发生大叛乱后,东印度公司将它的管理事务交付给英国政府,印度成为英国的直辖殖民地)。
莫卧儿帝国皇帝沙阿南将税收权转让给东印度公司

你要是从亚洲专制国家的角度来看,这种事实在是匪夷所思;但在封建体系下,这是完全正常的事情。哈德逊湾公司(北美最早的商业股份公司,也是全世界最早的公司之一。曾是全世界最大的土地拥有者,控制了绝大部分英占北美地区几个世纪的皮毛贸易,同时也承担了早期北美大陆的开发探索,在大移民潮到来前实际上成为了当地的政府。今天,公司成为全加拿大最著名的百货公司)和伦敦冒险商公司(即商人冒险家公司,是15-17世纪英国规模最大的商人组织,唯一拥有出口呢绒权的合法机构。初建于1407年,当时亨利四世授予在尼德兰经商的英国商人特许状;1564年伊丽莎白女王为公司颁发了新的特许状,正式授予它商人冒险家公司的称号。它驱逐了长期控制英国海外贸易领域的汉萨同盟势力,与荷兰进行商业竞争,实现了英国海外贸易的自主,促进了海外贸易产品由出口初级产品到制成品的转型)没有什么区别,它们都是去做买卖的。做买卖的过程和交涉过程中间,它得到了特许状,特许状允许它购置土地,在土地上行使自己的章程。如果它去的那些土地条件合适的话,它就自然而然地形成一个自治团体。其实公司本身就是一个自治团体。1854年在上海建立的租界组织(1854年7月11日,上海租界行政委员会成立,不久更名为市政委员会,中文名为工部局)就是这样的自治团体,它建立在所谓的租界土地章程的基础上。土地章程就是大清和大英两国君主准许在上海的欧洲人自己租地——而且还不是买地,在租来的土地之上,他就可以进行各式各样的经营。上海工部局也就是在这个体系下建立的。香港的政治制度也是在这个体系下建立的。

大家不要以为这是很特殊的东西,也不要以为这是欧洲侵略的产物,因为这恰好就是中世纪欧洲最经典、最正常的统治方式,伦敦的自治市议会也是这样建立的。无非就是,一群商人送了一笔钱给国王,国王再拿一个特许状,然后他们就自己组成了一个委员会,自己治理自己。如果要修路灯呢,大家自己想想,一人出一笔钱,凑齐了这笔钱修路灯;如果要修道路呢,我们也是开一个会,自己出一笔钱来修道路。这些会议渐渐就变成常规和正统的会议,就变成了市议会。而国王给的特许状就变成他们宪法的基础了。欧洲的自由城市,汉萨同盟(德意志北部城市之间形成的商业、政治联盟。13世纪逐渐形成,14世纪达到兴盛,垄断波罗的海地区贸易,并在西起伦敦,东至诺夫哥罗德的沿海地区建立商站,实力雄厚。15世纪转衰,1669年解体)、五港同盟(11-16世纪英国历史上东南肯特郡和萨塞克斯郡沿海的几个港市所组成的自治联盟,长期是英格兰重要的战舰来源和兵力后盾。最早作为核心的五港包括黑斯廷斯、罗姆尼、海斯、多佛和桑威奇,后来加入同盟的港口数量远多于五座,但五港同盟的名称一直延用。同盟向雅茅斯派遣治理官员(portreeves),并拥有鲱鱼的定价权和往来贸易船只的关税权。1215年五港同盟和伦敦作为英格兰城市的代表被写入《大宪章》)之类的,都是这样起来的。欧洲自治的源泉,就是从特许状和自治市政开始的。它在东方制造出来的体系也是这个体系。所以,英国商人跟大清的冲突,不一定是英国国王跟大清的冲突;上海的工部局跟大清的关系,也不是英国政府跟大清的关系。如果这两者有什么不同的话,其实就是:上海的工部局那些自治议会成员,是很高兴把上海拉出来搞成一个单独系统的;而英国政府反倒是没有这样的积极性的。东方国家开始跟西方相接触的时候,产生的就是这样的东西。

这种东西,有些人把它称为治外法权。但是我们要明白,治外法权是中世纪欧洲的正常状态。像伦巴第(位于意大利东北部)的商人在巴黎,他们是怎么样经营呢?法国国王给他们治外法权,让他们组织自治团体。法兰西的法律不适用于伦巴第商人,伦巴第商人继续按照意大利的习惯法自己治理。犹太人在波兰是什么状况呢?波兰国王或者立陶宛大公(1569-1795年间波兰王国与立陶宛大公国结为联邦)宣布犹太人是受波兰国王和立陶宛大公保护的人,在犹太社区里,他们自己选举出自己的拉比当政,不受基督教会和波兰习惯法的统治。意大利商人或者汉萨同盟商人在伦敦是什么状况呢?爱德华三世国王授予他们一个特许状,规定伦巴第商人有自治权,规定汉萨同盟商人在英国境内建立自己的法庭,根据他们自己的习惯法自己管理自己。欧洲完全是这个样子的。在欧洲法国大革命以前,所有的欧洲政权实体都是按照这种方式管理下来的。罗马教皇在法兰西境内的阿维尼翁有自己的飞地,在这里行使他自己的管辖权。即使在巴黎,在法兰西国王的系统之外,还同时存在着洛林公爵的法庭(洛林公国位于德法之间,1766年并入法国)和其他许多大诸侯的法庭。这些法庭管理这些诸侯的附庸,尽管在地理上是在巴黎境内。
汉萨同盟

你如果从近代领土国家的思路去考虑就会觉得,甚至连最高度中央集权的法兰西王国,也没有资格算是一个主权国家。法兰西国王在他的境内面临着成千上万种他自己都数不清楚的无数封建特权,这些特权他必须尊重。如果国王和这些领主的法庭发生了争论的话,他自己也少不得要到巴黎的国会去打一打官司,搞一搞登记状这些东西,他不是每次都能赢的。孟德斯鸠本人做官的波尔多法院,它并不一定非要承认巴黎那个法院登记发布的法令。即使在法兰西王太子担任领主的多菲内(位于法国东南部),也有数不尽数的习惯法。这些习惯法要根据本地的习惯法的法庭来审理,并不受巴黎的中央集权的管辖。像英格兰这样的地方那就更不用说了,它的多元性比法兰西要大得多。

就是在这些高度多元的环境中间,创新才容易产生。一元化的、整整齐齐的官僚体制,它不是加强了创新的可能性,而是收割了已有的创新成果。如果说它看上去比较强大,那不是因为它所统治的社会比较强大,而是因为它能比较有效地把社会创造出来的财富和力量集中到自己身上。即使在欧洲也是这个样子。法兰西大革命以后,近代民族国家产生,它产生的效果是什么呢?是简化,把我刚才描绘的这一个像神经元一样复杂的图景,简化成为在地图上可以画出来的、方方正正的各个领土国家。

这样做是造成了很多问题的。法兰西大革命造成的法兰西共和国是第一个拥有领土主权的国家,这造成了很多问题,比如说像洛林的贵族,在法兰西列王在的时期,他们虽然向法兰西国王效忠,但是他们同时还在神圣罗马帝国的帝国议会中有席位,他们对法国国王有封建义务;与此同时,他们又是日耳曼人,讲的是德语的一种方言,他们在神圣罗马帝国的帝国议会中有不可剥夺的权利。而法兰西共和国单方面撤销了这些权利,宣布洛林纯粹是法兰西的领土,这就意味着它撕毁了它跟神圣罗马皇帝、跟维也纳宫廷签署的条约,导致了法兰西共和国和神圣罗马帝国立刻进入战争状态。像阿维尼翁这种地方,如果法兰西共和国要统一政令和司法制度,那么它就立刻撤销了罗马教皇设在阿维尼翁的宗教法庭和管理体系,取消了罗马教皇通过他作为阿维尼翁领主所得到的封建收入。因此,法兰西共和国一旦采取了这样的行动,就立刻跟罗马教皇进入了战争状态。
▋法国大革命口号之一:We accept God, (a deist idea of god) but we revolt against Christ the King!

而跟罗马教皇进入战争状态,又使它跟与罗马教皇有保护关系的所有欧洲封建君主进入战争状态。而这些君主中间有一部分是德国的诸侯,而这些德国的诸侯跟汉诺威的君侯有联姻关系,汉诺威家族又恰好是英格兰王位继承人。所以法兰西共和国采取的这种建立主权国家的做法,就立刻把它推入了跟整个欧洲的战争当中。废除洛林和阿维尼翁的原有权利,它就立刻要向普鲁士王国、奥地利皇帝、罗马教皇和萨瓦公爵(现在属于法国的萨瓦省在1860年以前不属于法国。公元1003年,萨瓦伯国建立,统治中心在尚贝里; 1416年,萨瓦伯国被擢升为公国;1563年,萨瓦公爵将统治中心迁到了都灵;1720年,萨瓦公爵被擢升为撒丁国王,同时兼任萨瓦公爵;法国大革命时期,萨瓦地区被法国占领;1860年,根据都灵条约,萨瓦地区并入法国;1869年,意大利王国宣告成立,最后的萨瓦公爵、撒丁国王维克多艾曼努尔二世成为意大利国王)宣战。而这些君侯的联姻关系,使它必须向德国北部的大多数诸侯宣战。而向德国北部新教诸侯宣战的结果,又使它不得不向英国和瑞典国王宣战,因为三十年战争以后,这些新教诸侯在条约体系中间是由英格兰国王和瑞典国王负责保护的,侵犯他们就是侵犯英格兰和瑞典。

近代民族国家就是在法兰西大革命以后掀起的一系列腥风血雨中建立起来的。战争之所以要爆发,主要就是要把过去那种多元的、多层次的条约结构,变成民族国家产生以后的那种单元的、平面式的条约结构。现在我们熟悉的这种情况,外交属于中央政府层面,法兰西政府和德意志政府签署条约,底下那些各个团体都没戏,这绝对是十九世纪以后才有的事情。

不仅法国大革命引起的战争是因为废除封建原有的成规引起的,而且十九世纪的大多数战争都是这样的。像普鲁士掀起的德意志统一战争,它是始于普鲁士和丹麦王国的封建纠纷。像石勒苏益格-荷尔斯泰因(位于德国北部。荷尔斯泰因公国在中世纪属于神圣罗马帝国,1815年后属于德意志同盟,但丹麦国王是其君主;石勒苏益格公国北部居住的主要是丹麦人,而南部居住的主要是德意志人。1864年的普丹战争就是为此纠纷而爆发的。1920年,北石勒苏益格进行公民投票,决定与丹麦合并。1955年德国与丹麦之间再次签署条约)这些小公国,它像洛林公国或者是阿维尼翁一样,也是有多重契约关系的:他跟丹麦国王有封建关系,跟神圣罗马帝国也有封建关系,又是维也纳会议所确定的条约体系的一部分。你说它是属于德国还是属于丹麦?这个问题本身就是错误的。因为只有按照现在领土国家的规矩,你才会说每一个地方都应该固定是属于某一个国家的领土,它属于某一个国家就不能属于另外一个国家,我们不应该干涉他国内政,诸如此类。但是按照当时的惯例,根本不可能这样说。当地的公爵本身就有几个不同的宗主,他底下的小领主,又是在不同地方登记的。财产权这个东西,资本主义最重视的财产权,本身就是封建体系的一部分,在普通法和日耳曼习惯法当中都是这个样子:也就是说当地的某个地主,比如说是瑞士某一个城邦的某一个农民,买了一块土地,你不要以为我付了钱这块土地就是给我了,这不大可能。瑞士的某一块土地,或者是欧洲的任何一块土地,它上面都附加着错综复杂的封建义务。

它原先的主人可能会根据他在1142年签署的协定,跟附近的修道院长某某某,每个季度要进贡三桶葡萄酒。还要跟巴本堡家族(起家于法兰克尼亚(今德国巴伐利亚州北部)的巴本堡,在哈布斯堡王朝崛起之前,这个家族的成员在976—1248年间先后以藩侯和公爵的身份统治奥地利)的后裔,逢年过节的时候,送上一些土特产作为礼物。你只要买了这片土地,那么你就继承了这片土地相应的封建义务,你也就是这些某某某修道院长或者是巴本堡家族某个后裔的附庸,需要给他尽义务。然后你要考虑到,巴本堡家族后来只有女性后裔而没有男性后裔,所以他们家女儿嫁到欧洲其他的贵族家庭了,也就把她自己的封建义务带过去了。比如说,他后来的外甥女的外甥女的外甥女的外甥女,嫁给了德国的荷尔斯泰因公爵或者是其他什么公爵;这个公爵的外甥女的外甥女的外甥女的外甥女,又嫁给了丹麦国王的弟弟;而丹麦国王弟弟的外甥女的外甥女的外甥女,后来又嫁给了俄罗斯沙皇;俄罗斯沙皇生下来的这个大公爵,后来又经过了大概一百多年时间,在后来的沙皇那里封到了很多土地,而沙皇陛下在跟土耳其人和奥地利人打仗的时候,征服了加利西亚(位于伊比利亚半岛西北角)的某些地方,又把加利西亚的某些地方封给了他。于是接下来的结果就是,瑞士这个农民因为买了这个土地,他按道理说应该把本地麦子成熟时,最先烤出来的那十二块最新鲜的烤面包,越过大半个欧洲送到这位加利西亚公爵大人在圣彼得堡涅瓦河边那个住宅去,这样才算是尽了他的封建义务。

刚才说的那个农民是封建体系的最底层,但是从最底层到最高层,这个道理是一样的。这样的高度复杂的关系操作起来,即使是最精密的法学家也会感到头疼的。像法兰克福帝国议会就雇佣了很多很多法学家专门干这种头疼得不得了的事情。任何人跟任何人打官司,都可以牵扯出几百年前、几百里外数不清的各种封建关系。像英国的蔷薇战争其实就是这种因为继承权拧不清楚搞成的战争。歌德在年轻的时候学法律,他研究的就是诸如此类的项目。

而十九世纪的战争,像我刚才描绘的那种战争,它骨子里有根本的目的,一句话说就是:解决这些错综复杂的交易的话,打仗比打官司还要便宜一点。你如果要把巴本堡家族和加利西亚的历史、把丹麦和俄国皇室涉及的所有联姻关系都搞清楚,你还不如干脆打一仗来得省事,或者发动一场革命,革命完了以后,大家重新签署一个条约,一块土地以后就只有一个主人。后期的近代欧洲的战争,很大程度上就是这样的。

我们都知道,光荣革命的主角是荷兰的奥兰治亲王(William III,1650-1702,1672年起为荷兰执政,1689年起兼为英国国王,他一生的主要事业即对抗路易十四),他跟法兰西的路易十四是死对头。他为什么恨路易十四呢?除了许多政治上的原因以外,还有一个原因就是,奥兰治亲王,他当然跟欧洲所有的贵族一样,他通过联姻和其他关系,他的产业不是只有在荷兰才有,也不是只有在英国才有,而是在什么地方都有。他在法国就有一些土地,从那些土地上也有一些收入,这些收入是他私人的收入,不是荷兰或者英国的国家收入。然后他跟路易十四打仗的时候,路易十四派了一支军队去把他的领地没收了。他这一辈子恨路易十四,最恨的就是这一件事情。为什么最恨这件事情?因为打仗是经常的事情,你和我打仗,我和你打仗,这是封建欧洲的正常关系,但它是应该的,路易十四也跟别人打仗,他也跟别人打仗。但是打仗你要守规矩,你跟我打仗,跟我的领地有什么关系呢?你法兰西国王难道在荷兰或者英国没有什么领地么,在国外没有什么领地么?你没收了我在法兰西的领地,这是违反封建主义的成例和习惯法的。如果要这么干的话,那么我们跟其他人打仗的时候,是不是别人在英国的领地我也给没收了,我也把他们的产权都给侵犯了?
1672法荷战争

别的地方不说,在英国,这一点你是做不到的。如果外国贵族在英国有什么领地的话,那么即使英国在打仗的时候,英国法庭也不可能去侵犯它,国王也不可能命令法庭违反普通法原则去侵犯他们的财产权。像法国大革命的时候,尽管英法两国已经交战了,但是法国贵族如果跟当地不和,向夏多布里昂(1768-1848,法国诗人、保王党人,波旁王朝复辟后曾任贵族院议员、驻英大使等职)这种人,他在法国混不下去了,一股脑就逃到英国了,他可以理直气壮地索取他在英国的产业,英国是不能没收他的产业的。但是反过来就不一样,法国的革命党和拿破仑都毫不犹豫地没收了英国人在法国的产业。所以威灵顿公爵就说,波拿巴是一个流氓,他不是绅士。这就叫不是绅士。

在20世纪也有类似的情况。比如,斯大林占领了爱沙尼亚(1940年6月,斯大林故意挑起事端,恐吓波罗的海三国,逼迫他们“自愿加入苏联”。8月,三国被迫“请求加入苏联”),他就把爱沙尼亚的地主和资产阶级的产业全部没收了,但是爱沙尼亚流亡政府跑到国外去,虽然几十年来没有加入联合国,也没有任何国际法正式身份,但是他们存在英国和美国银行里面的黄金和财产,英国人和美国人一直给它看得牢牢的,直到苏联解体,爱沙尼亚复国,复国的新政府马上就可以跑到英国和美国银行去,要求把我们还没有被苏联吞并的时候存在你们这儿的钱还给我们,而英国人和美国人会乖乖地把钱还给他。这就是封建主义和民族国家的不同。所以法国大革命和拿破仑首先建立民族国家的时候,当时人对这种野蛮的新政体的观感,那就像是丘吉尔这种人看到列宁和布尔什维克肆无忌惮地没收私有财产的感觉一样,你们就是一群野蛮人。

但是故事是两方面的:一方面,你要顾及到原有的权利和契约,尤其要顾及到体系的多元性;另一方面你要顾及到交易的简便性。民族国家体系之所以能够建立,归根结底,它在交易的简便性方面有所进步。近代社会的博弈是高度复杂的,任何简化的说法都是挂一漏万的。但是即使这样,我今天仍然按照简化的说法说。道理很简单,如果按照复杂的说法说,那么花上一年时间也讲不完。所以刚才已经讲得太繁密了,已经讲了这么大半天还没有讲到中国。

(二)

梁启超、蒋介石和中国的革命家没有通过神意裁决。他们失败了,中华民族仍是一个纸面上的概念,它避免不了以后的新的神意裁决。

大清跟西方相接触的时候,西方不是一个已经固定的模型,它本身就是一个正在不断产生新生事物的演化体系。如果你能弄明白演化体系这件事情,那你就会比任何学历史的专业学生要更聪明了。我觉得企业家对这一点应该比较容易理得清,因为市场经济本身就是一个演化体系,它也是在不断变化的。但是科班的学者反而不容易搞得清,因为他们自己就生活在科层制度之中,特别不容易领会动态演化的概念。他往往是由于自身心理结构的缘故,把一个明明是在不断演化的系统当成一个凝固的系统。基本上所有近代史观都是这样的,你看他们的著作总是英国人如何法国人如何,好像当时英国和法国已经存在了。其实不是。当时跟中国打交道的所谓的英国和法国,自己就是一个不断演化的体系。欧洲也是一个不断演化的体系。所以大清的士大夫对欧洲的理解之所以这么错乱,那也是道术为天下裂。从具体的某一个碎片上来看,他们也许说得没错;但从整体上来讲,他们没有抓住演化的脉络。

我们用比较粗略的、高度简化的方法来说,欧洲的秩序演化,从十九世纪开始到现在也是经历了好几波的:第一波是封建余波的多元权力结构,建立上海租界、汉口租界和香港租界的是这种体系,上海的工部局、香港殖民地、各地租界什么的,代表了这一个体系的秩序输入;第二波是法兰西革命以后,特别是普法战争以后的民族国家建构,后来的中华民国以及以后的各个政权是这一波影响的结果;第三波则是第一次世界大战以后由布尔什维克开创的这种跨国性的意识形态战争;第四波呢,则是苏联解体、冷战结束以后,亚国家组织和超国家组织开始瓜分现有的民族国家体系的过程。大体上是四个阶段。
1841年的 香港
19世紀末的香港
1843年的 上海灘
1897年的 外灘

但是大家不要忘记,这是一个演化体系。演化体系所谓的四个阶段类似于,我说你是一个人,你有小孩的阶段、青年的阶段、中年的阶段和老年的阶段,我不能武断地说,二十岁就是青年而不是小孩。这是人各有异的,只是一个大体模糊的标准。只能说从十四岁到二十五岁这个阶段,你渐渐由小孩变成青年。刚才所谓的四个阶段也就是这个样子的。它们的分划是模糊的,没有一个固定的时间界限。模型的演变也像是小孩变成青年、青年变成老年一样,是一点一点变的。你要具体找出在某一个点上他突然发生戏剧性变化,这是不可能的。变化是渐变的。所谓的特征,像是人体的标准解剖图那样,也是不存在的。只是一个大概的模型而已。

东亚社会的问题在于,它在接受输入的过程中,一方面是输入的四种体系本身都比东亚原有的体系更强大,它们不断削弱甚至替代东亚原有的体系;另一方面是,你在还没有学好第一种体系的情况下,第二种体系就进来了,第二种体系还没有学会、还没有建立起来,第三种体系就进来了。有很多事情,其实是欧洲从旧到新的不同体系,在东亚这块土地上相互打架的结果。把它当成新派和旧派的区别也不对,当成左派和右派的区别也不对。其实这就是欧洲的老一代的思想苗裔和新一代的思想苗裔不断打架的过程。

从清朝末期以来的政治建构就可以看出,李鸿章时代西方输入的政治建构其实还是前民族国家那一套,治外法权这类东西。它输入的是什么呢?输入的是一个多元多层次的权利体系,它容许各个商团产生出自己的领事和代表,容许私人交涉,容许商团之类的组织建立自己的习惯法法庭、自己的军队和诸如此类的东西。大清士大夫和后来的革命史学家把这些当成是侵犯大清主权的事情。但是首先,大清没有主权,它自己就不是一个主权国家;其次,这种“侵蚀方法”,其实是欧洲体系向海外的自然扩张。
上海会审公廨審案情景

第二波的产物就是我们所说的民族国家。民族国家是封建主义解体的产物。封建主义只要求你效忠具体的一个有身体的国王或者是君主。所谓“国王有两个身体”①这样的学说就是针对这种封建主义的游戏规则而设立的。国王为什么有两个身体?因为他是一个人,一个具体的人当然有一个身体;但他另外还有一个政治身体,就是说他作为他所在的政治体系的代表需要行使的权力。既然革命以后要取消国王,那么原有的政治体系怎么维持呢?那么我们只能把“效忠国王”变成“效忠国民”。国民和国家是一个词。以前属于国王的一个具体的人的权力,现在由法兰西国民这个整体来行使。

1、“国王的两个身体”是中世纪普遍流行的一种观念。对它最完整的表述当属伊丽莎白一世时期法理学家爱德蒙·普洛登(Edmund Plowden)的《评论或报告》(Commentaries or Reports)。他在这本著作中写道:“国王有两个身体,即政治身体和自然身体。国王的自然身体是可朽的,会屈从于各种由自然或偶然的原因造成的虚弱、婴儿和老年时期的低能,以及任何其他的自然身体都可能具备的缺陷。但是政治身体是不可见、不可控的,它由政策和政府组成,其目的在于指导人民,并且为了人民的公共福利进行管理。政治身体彻底排除了那些自然身体所屈从于的婴儿期、老年期、其他的自然缺陷和无能。”

但是问题是,法兰西国王是路易十四或者路易十六,我们都能够找得出,路易十四说什么,这就代表了法兰西王国的意见了,但是谁能代表法兰西国民的意见呢?谁是法兰西国民,谁不是法兰西国民呢?巴黎人可以说他是法兰西国民,洛林人是不是法兰西国民(阿尔萨斯、洛林地区是加洛林王朝的发祥地,长期属于神圣罗马帝国,居民大部分说德语。16-18世纪,阿尔萨斯、洛林地区被法兰西王国逐步吞并,但保有司法、税收、贸易等方面的传统特权)?布列塔尼人是不是法兰西国民(布列塔尼公国位于现今法国西北部,早期与法兰西王国关系若即若离,一度被英格兰国王通过联姻控制,后又逐渐脱离英格兰的掌控。百年战争时为英法双方都争取的对象,1532年被法国合并)?阿维尼翁人是不是法兰西国民(位于今天法国东南部沃克吕兹省。1305年间,法国国王腓力四世操纵波尔多大主教任教皇,即克莱门特五世。1309年,教廷从罗马迁至阿维尼翁,受法王控制。1377年迁回罗马,但阿维尼翁仍属教皇领地)?这就很难说了。国民取代国王,那你就要求把国民共同体的边界划出来。你必须说清楚。以前的阿维尼翁人可以说是有不同的宗主,这无关紧要;现在呢,他就必须选择,你是法兰西国民还是意大利国民。你不可能同时是两种国民了,否则后来的政治体系安排不起来。
自由引导人民

国民这个概念一产生,民族国家就产生了。你必须武断地划出来,某一个地方的居民,你现在是法兰西国民,或者是德意志国民,或者是奥地利国民,这样做,新的国家体系才能够建立得起来。这个国家体系的拆分就是武断和单元的,而且本身也是没有什么道理的。你很难说为什么法兰西国民应该存在,而布列塔尼国民就不应该存在。德意志民族为什么不能包括奥地利民族(奥地利一直是神圣罗马帝国的重要邦国)?波西米亚人为什么不能算是德意志的一个方言区,偏要算是一个独立民族(波西米亚长期属于神圣罗马帝国)?这都是没有道理可讲的,只能有先验的理由讲。所以从十九世纪晚期一直到二十世纪末期,反殖民主义主要的困难就是要在没有国民共同体的情况下建立国民共同体。建立了国民共同体以后,你才能实施有效的统治,对内你才能够建立宪法体制,对外你才能够搞国际交涉。

相对于东亚来说,这就是梁启超和汪兆铭的时代(参看阿姨《“中国”之父——历史发明家梁启超》、《汪兆铭的共同体与先锋队——在民族主义与列宁主义之间》)。他们要解决东亚社会需要建立一个什么样的国民共同体的问题。对于大清来说,这是没有必要的。大清可以建立各种具体的保护关系:大清皇帝作为满洲人的酋长,他是满洲八旗的天然领袖;作为成吉思汗的继承人(自皇太极起,清朝皇帝兼任蒙古大汗,称号是博格达彻辰汗),他可以统治蒙古各部落;作为明朝的征服者,他对十八省行使征服者的权力;同时他还和朝鲜国王、越南国王有各种不同的具体关系;他跟西藏的达赖喇嘛有一种宗教意义上的保护人的关系。这些千奇百怪的关系是不能用主权来衡量的。他签署的各个契约也是千奇百怪的。

在欧洲自己的外交结构正在发生演变的情况下,大清也就必须面临选择了,面临着神圣罗马帝国式的选择:要建立一个大德意志民族?还是小德意志民族?梁启超所设计的中华民族(1901年,梁启超在《中国史叙论》中首次提出“中国民族”的概念,次年又在《论中国学术思想变迁之大势》中提出“中华民族”的概念),它本质上就是想要把大清帝国多元的各个层次重新组合起来,建立一个类似于欧洲地方性国家的民族结构。但这样做毛病非常之大。因为大清和神圣罗马帝国一样,它是天下,它不是国家。神圣罗马帝国之下,有各种不同的族群和政治结构,它的统治是象征性的,是一种道德上的和礼仪上的权威。它统治整个基督教世界,它不需要有具体的领土,因为基督教世界的领土边界也是不确定的,它可以在波兰和乌克兰的边界,也可以在乌克兰和俄罗斯的边界。只要你们都是基督教徒,神圣罗马皇帝就可以说,你们的世俗权利都归我处理。同样的道理,如果你们都是东正教徒的话,那么君士坦丁堡那位大主教就可以说,你们都是我的臣民,尽管我是受土耳其苏丹这个穆斯林保护的,但是我还是有权力指挥亚历山大(埃及亚历山大城)和莫斯科的东正教徒,尽管他们都不在君士坦丁堡的苏丹保护之下。简化这种体系就产生了刚才所说的民族国家。而梁启超和后来人,他们的所作所为,归根结底就是要简化这个体系。
1898年世界殖民状态

简化这个体系,在欧洲,撕毁原有的多元体系,就造成了法国大革命以后的战争;在中国就造成了辛亥革命以后的各种战争。因为大清还可以保持暧昧,大清皇帝是一个具体的人,还能够根据原有的多元体系,保持多元体系的一部分特色;而中华民国,像法兰西共和国一样,没有这个具体的人了,它要行使统治权,你就必须搞清楚它的主体是谁。中华民族的主体是谁呢?是炎黄子孙呢还是五族呢?这就是非常重大的问题。你如果按照黎元洪和孙文的意见,或者按照蔡锷的意见,那么显然,满洲人和蒙古人就不是炎黄子孙,而我们之所以闹革命,最重要的就是要把朔方弩骑赶出长城;而按照袁世凯的意见呢,那么大清治下的所有居民都应该算是五族共和的一个主体。中华民族的主体是五族,尽管这是一个很矛盾的概念。五族,按照这个定义来说,它就不是一个均质化的国民共同体,它要产生出自己的公共意志是极其困难的。国民共同体实施有效统治,那它的宪法结构必须容许它的各个部分能够产生出一个一致的公共意志。这就是假定,国民共同体,它必须是一个均质化的团体。法国人建立国民共同体,他的基本逻辑就是启蒙运动的原则,我们不再根据法兰西国王的政治效忠了,而是说,拥护理性、启蒙、进步的原则这些新的原则就是法兰西国民的条件。

而德国人在浪漫主义时期,在格林和哥廷根学派时期发明的新的民族概念则是,根据语言和习俗的共同体(“哥廷根七教授”之一的雅各布·格林既是《德语语法》、《德语词典》的编撰者、《格林童话》的收集者和改编者,又是哥廷根历史法学派的先驱者、德国民族自由主义(1849年哥达议员团)的力行者。他毕生行迹就是以发掘民俗文化为重构民族神话打基础。参看阿姨《发现人民、创造民族——从大众文化到民族国家》)。如果我们用共同的语言和习俗,我们就应该建立一个独立的国民共同体。但是什么是语言,什么是方言呢?这又是说不清楚的事情。你说德语是一种语言,那么波西米亚语是不是德语的方言呢?那么我们是不是可以说,拉丁语根本就是一种语言,法语、意大利语、西班牙语、加泰罗尼亚语它们都是拉丁语的不同方言呢?拿破仑三世(Charles Louis Napoléon Bonaparte,1808-1873,法兰西第二帝国皇帝,拿破仑的侄子,推行泛拉丁主义,积极干涉美洲事务)就是这种主张,他认为拉丁语是一种语言,法语和西班牙语的差别,就像是普通话和粤语的差别一样,因此所有的拉丁国家都应该在他的领导之下统一起来,共同对抗盎格鲁-撒克逊人。他入侵墨西哥就是根据这种逻辑。因为拉丁美洲,他留下的政治遗产就是拉丁美洲这个词,在他以前没有人提拉丁美洲这个词的。现在为什么叫拉丁美洲?就是因为法国人想统治整个拉丁语的世界。那么,比如说撒克逊的方言,它算不算一种语言?按说的话其实也可以算。撒克逊的方言跟高地德语和低地德语之间的差别,至少比丹麦语和挪威语之间的差别要大。
▋第一任挪威国王哈康七世(丹麦国王弗雷德里克八世的次子)与莫德王后

丹麦语和挪威语,直到1895年以前,没有人认为它们是两种语言的。包括安徒生和易卜生这种人,他们都不会认为这是两种语言。各位看《安徒生童话》的时候就可以看到(《破布块》),安徒生在写童话的时候还不忘嘲笑他们。他描写一个挪威的烂布和丹麦的烂布打架,说挪威的烂布不断地吹牛说,我们挪威的宪法像美国的自由宪法一样好,我们挪威的语言比你们丹麦的语言不知道高到哪里去了。但是实际上挪威的语言和丹麦的语言只有几个词、几个拼法的差别。在安徒生的时代,也没有人觉得它们之间有什么差别。为什么一定要说挪威语是独立语言?就是因为挪威独立了。挪威独立以后,他就要硬着头皮说,我们不是丹麦语的一种方言,我们是一种独立的语言。然后把小事放大,本来只有几个字母和拼法的差别,一定要说它是不同民族的不同语言。你要真从差异角度说的话,那么挪威语和丹麦语很难说是不同语言。

而加泰罗尼亚语,它跟托斯卡纳语的关系很近,而跟卡斯蒂利亚语的关系就比较远了。至于巴斯克语,巴斯克语跟法语和西班牙语的差别是非常之大的,比法语和西班牙语之间的差别还要大。如果按照德国人发明的这种民族理论,我们完全可以说,讲法语的人和讲西班牙语的人应该建立一个统一的法兰西-西班牙联合王国,而中间,比利牛斯山里面的巴斯克人则应该建立一个巴斯克独立王国。

所以无论按照哪一种国民或者民族理论,都会留下无穷无尽的纠纷。这种纠纷在欧洲导致了整个十九世纪的战争;在欧洲之外呢,因为它们是下游地区,所以波及比较晚。远东地区二十世纪的战争基本上是为此而展开的。东南亚和非洲国家在1960年以后的战争,其实主要也就是为了这个。这些战争的基本目的,主要就是为了在没有民族和国民的地方,通过战争和革命,制造出民族和国民的概念来。

像蒋介石,他在抗日战争的时候就大发牢骚说,为什么我国军队在我国自己的土地上作战,却得不到本国人民的支持?我们在湖南作战的时候,湖南本地的人民像是看戏一样看我们跟日本人打仗,我们军队如果丢盔卸甲了,丢下的战利品,当地老百姓会毫不犹豫去抢,这难道是本国人民对本国军队应有的做法吗?但是这种做法一点也不离奇啊。在前现代社会,不用说,在大清朝也好,在汉朝也好,或者在任何时候也好,老百姓是不管这一套的。刘备的军队也好,曹操的军队也好,只要来了以后总要征粮征款,如果打了败仗,当地老百姓也肯定要抢他们的。四川人既不会说,诸葛亮是代表我们大蜀民族的一支军队,我们要主动协助他;曾国藩的军队也不可能因为说,我们是代表湖南人的军队,湖南人就会对我们特别好。欧洲在三十年战争(发生于1618-1648年,以德意志新教诸侯和丹麦、瑞典、法国为一方,并得到荷兰、英国、俄国的支持;神圣罗马帝国皇帝、德意志天主教诸侯和西班牙为另一方,并得到教皇和波兰的支持。主战场在德国)的时候也仍然是这个样子的。各路的军队在德国的土地上打仗的时候,他们都是要抢劫的。当地的人民对谁也没有什么特殊的效忠。国民共同体和特殊效忠的这个观念,在欧洲也是十九世纪的产物。所以蒋介石得不到这种效忠,那是很自然的事情。

但是从反方来说,日本人却得到了这种效忠。日本国民通过长期的军国民主义训练,已经在它自己的国内培养出了相应的认同和效忠。日本人要招兵的时候,就像梁启超在清末看到的时候,广大人民是踊跃参军的。妻子把丈夫送上前线,还打着“祈战死”、“勿生还”的旗号。梁启超当时在日本,看到这种情况,跟大清国那种老百姓看热闹比起来,他就觉得日本太先进了,有必要好好宣传一下他们。大家都知道鲁迅《藤野先生》那篇文章,他说中国人麻木不仁如何如何,其实中国人这种概念就是他同时代的人发明出来的。大清臣民当然是麻木不仁的。清朝军队照样抢劫他们,而日本人和俄国人来了以后,还给他们运了不少的救济粮,他们没有理由觉得清朝有多好或者日本人和俄国人有多坏。
▋二战时日本陆军参拜靖国神社:“为了天皇、为了祖国日本奉献生命”

你可以从更加客观的角度来看,蒋介石和日本人的差异在哪里?就是,日本是一个已经建立起来的民族国家,而蒋介石则是企图建立民族国家而没有建立成。建立不起来,一方面是因为他建立得比较晚,另一方面就是他野心过大,他要建立起来的这个中华民族横跨的领域太大。不要说是长城以外的地方了,就是湖南人和广东人之间都很难合作得起来。孙中山他们在革命的时候就对这一点有很痛切的感觉。搞到最后,孙中山能够号令得动的也只有广东人,而两湖地区的同盟会员跟宋教仁关系比较好,跟共进会关系比较好,总之是不服他。江浙地区的革命党人宁可跟着章太炎和光复会走,恨孙中山的程度是超过恨袁世凯,他们最后宁愿跟袁世凯和黎元洪结盟,也一定要把孙中山搞下来。十八省尚且如此,关外又怎么能够做到。你没有能力做到,而又一定要破坏原有的条约体系,那就很麻烦了。

从国际体系的角度来看,蒋介石政府的革命外交,比如说,废除治外法权、把日本人和苏联人赶出东北这些做法,其实不新鲜。第一,它们都是违反条约的;第二,违反条约的不仅是他们,这是法国人早就干过的事情。法国人把德国人赶出洛林,把罗马教皇赶出阿维尼翁,这些事情就是蒋介石把日本人和俄国人赶出满洲的同类。为了建立单一的民族国家主权,那你就必须撕毁原有条约,因为原有的条约是在多元体系基础上建立的。撕毁原有条约,那你就必须要付出战争代价。

但是接下来的结果就不同了。我们可以看出,法兰西的革命军和拿破仑有能力撕毁条约,而蒋介石和国民党的军队则没有能力撕毁条约。这就是他们重大的差别了。照西方政治学里的说法,什么是战争?战争是神意的裁决。法兰西民族原先是不存在的,在法兰西大革命以前没有法兰西民族、没有法兰西国民,只有法兰西国王统治下的法兰西岛等各财政区,有法兰西国王统治下的诺曼底公爵领地、布列塔尼公爵领地、洛林公爵领地、勃艮第公爵领地、里尔自治市、阿维尼翁和斯特拉斯堡等各个自治市,没有什么统一的法兰西国民。如果法国革命军被普鲁士人打败了,如果普鲁士人打进巴黎把路易十六放了出来,如果封建欧洲各国的联军毁灭了法兰西革命军,那么民族国家就不会存在了。
▋1800年6月14日拿破仑在马伦哥之役大败奥地利军,迫使第二次反法同盟解体。

民族国家通过法兰西大革命和拿破仑,通过了神的考验。神的考验就是什么?它不是所谓根据法律来做出来,而是要推翻整个原有的法律体系的。我们要知道,按照旧欧洲的法律体系,罗伯斯庇尔和拿破仑·波拿巴都是大逆不道的弑君犯和违法者,他们破坏了原有的法律,他们是条约破坏者,他们是希特勒,他们破坏了原有的条约体系,就像希特勒破坏凡尔赛条约这种体系一样。谁是罪魁祸首?拿破仑和法国革命家是罪魁祸首。谁不应该存在?法兰西共和国不应该存在。法兰西共和国存在本身就是对条约体系的破坏。

但是法兰西共和国通过了神的裁判,也就是说是,它打赢了,因此法兰西共和国就存在了。它不仅存在了,而且因为法兰西共和国的存在,产生了新的合法性标准。法兰西共和国以外的各地,特别是德国和东欧,也想要模仿法兰西共和国建立新的民族国家,于是就有了德国统一运动,有了意大利的统一运动,有了波兰的复国战争,有了罗马尼亚、捷克斯洛伐克这一系列新国家,有了德意志帝国和苏联帝国的解体。这一切都是从法兰西共和国开始的。战争是神意的裁决,法兰西共和国通过了神意的裁决,不仅使法兰西民族得以存在,而且使全世界的民族国家都得以存在。

然而,梁启超、蒋介石和中国的革命家没有通过神意裁决。他们失败了。他们失败的结果就是中华民族始终和过去的大清帝国一样,是一个纸面上的、纸上谈兵的概念,它避免不了以后的新的神意裁决。这才是我们现在面临的中国问题的一个根本。为什么我们近代以来讨论中国问题总是讨论不出一个所以然呢?就是因为中国还不像法兰西共和国一样,是一个已经建立的东西,它像法兰西共和国以前的欧洲一样,处在演化未定的不确定状态,多种模式不断在里面博弈。

▋声明:上期有关“加利西亚”的注释应该是“西乌克兰”,而非“伊比利亚半岛西北角”,小编注释有误,与阿姨沟通确认后特此公告给大家。

(三)

在世界革命最终成功以前,为了欺骗和利用资产阶级,列宁主义集团必须制造一个semi-state,一个半邦国,一个假国家。

于是就爆发了以北伐战争和国共战争为代表的战争。结果,抗日战争以后的情况是怎么样的?是不同的游戏规则搅在一起了。抗日战争从本质上包含了两种成分。第一,它是中华民族如果要存在必须做到的撕毁条约体系的做法,它是法兰西大革命和拿破仑战争在远东的翻版,然而这个准备建立的中华民族没有通过神裁。北伐战争和国共战争是什么呢?它是列宁主义的新型国家企图推翻法兰西共和国建立起来的民族国家体系。这种新型国家,它不承认边境的存在;而法兰西共和国建立在国民共同体的基础上,它的首要条件就是要把国民的边界搞清楚。

法兰西共和国是法兰西国民的国家,主权属于法兰西国民。那么波兰共和国是什么呢?它只能是波兰国民的国家。波兰民族必须像法兰西民族一样划定边境。中华民族如果要建立中华民国,那么你就必须首先把中华民族建构起来,像法兰西民族和波兰民族一样,说清楚谁是中华民族,谁不是中华民族。要做到这一点:对内,你要么把那些无法同化的族群赶出去,要么就把它同化掉;对外,你要撕毁原有的条约结构。这是你要建立这样的一个民族国家的必要的准备条件。

而列宁主义国家的特点恰好相反,它是要撕毁边界的。列宁主义的基本观点就是,民族共同体是资产阶级的骗局,它是为了欺骗无产阶级、掩盖阶级斗争的本质而设的骗局。世界上只有两个真正的共同体,一个是无产阶级的共同体,一个是资产阶级的共同体。这两个共同体都是不分国界线的。资产阶级欺骗无产阶级,让本国的无产阶级效忠本国的资产阶级而反对外国的资产阶级,因此使得无产阶级的统治无法实现。我们为了实现无产阶级的统治,首先就要打破这个幻觉,要明白,无产阶级只有一个祖国,那就是苏维埃祖国,其他所有的祖国和民族都是资产阶级制造的虚假共同体。因此,列宁主义国家是要打破这个边界的,它和原有的民族国家——法兰西共和国所代表的民族国家是不能两立的。

于是就出现了这样矛盾的情况:中华民族还没有建构起来、中华民国还没有建立起来,它就已经首先面临着列宁主义革命政党的入侵。这个入侵就涉及很多具体的细节了,比如说你可以开一个长长的账单,从远东共和国(1920年4月6日至1922年11月5日之间,苏俄为了在其控制区域和日本占领区域之间设立缓冲地带而设置的傀儡国。该国对外宣称保护私有产权,实行门户开放,主动发展正常的外交关系,暗中向外派出渗透势力)的时代一直到朝鲜战争的时代,把账单开出来,看看国(略)两党在某年某月某日拿了多少卢布。这个账单是很容易开出来的。你把这个任务交给我,我马上就可以给你开出来。只是这样的书不知道能不能够出版,那是另一回事了。

结果就是,国(略)两党所代表的这种新型国家,在民族国家还没有来得及站住脚的情况下,就颠覆了原有的民族国家,建立了一个,至少它自己想要模仿苏联的一个列宁主义政权。而列宁主义政权,按其定义来说,它不是一个民族国家,它是一个运动着的交战集团。它是世界革命的一部分,其任务就是为了摧毁资产阶级社会。资产阶级社会和市民社会是同一体,干脆说吧,就是法兰西共和国的自我和他者,是在法国人和德国人、法国人和英国人、法国人和西班牙人这种标准上面。我们法兰西人是一家人,我们跟你们德意志人、英格兰人、西班牙人不是一家人,而是敌人或者是外人。

而列宁主义国家的实质是,我们是无产阶级的先锋队,我们跟全世界的无产阶级是战友,跟全世界的资产阶级是敌人。所以我们有两个敌人:第一就是国内的市民社会,我们要防止不断自发产生的资产阶级,资产阶级和市民社会是同一体,我们在国内的任务就是,通过无产阶级专政,行使永恒的战争权力,把这些不断自发生长出资本主义萌芽的市民社会土壤给铲平掉;对国外,我们要行使革命和颠覆的权力,把那些已经控制政权的资产阶级专政打掉,把他们已经建立起来的资产阶级民族观念给破除掉。这就是我们新型国家的基本任务。

按照Lenin的理论来说,无产阶级专政建立的政权,它不叫国家,它叫semi-state,它不叫nation。state跟nation不一样的。state是邦国,只要能够实施有效统治的邦国都叫state。比如说,勃艮第公国,苏格兰王国,它是可以叫做state的,但是它不能叫做nation,不能叫做民族国家。Lenin他不承认有nation和民族国家,因为nation和民族国家是什么概念呢?它就等于承认有一个真实的国民共同体,国民共同体有权通过选举或其他方式来决定自己的命运。而Lenin是坚决否定这种概念的,认为这纯粹就是资产阶级的欺骗。邦国呢,只要实行有效统治都可以叫邦国。但是即使如此,Lenin仍然不愿意把苏联或者无产阶级国家叫做state,他把它叫做semi-state,半邦国。

什么叫做半邦国?它是一种过渡状态。说得干脆点,它是一个统战的白手套。真正的统治者是布尔什维克和(略),但是在世界革命得以最后成功以前,我们还不得不跟资产阶级国家这些虚伪的国家一起混,而对这些国家是要按照英格兰、法兰西这些国家与国家的交涉方式去交涉的,我们如果没有一个国家作为白手套,我们没法跟它打交道,我们是要吃亏的。这样怎么办呢?尽管我们否定国家,但是我们为了统战和利用资产阶级,我们必须制造一个semi-state,一个半邦国,一个假国家。

这个道理跟政协会议的道理是一样的。为什么(略)要召集政协会议呢?虽然我们实际上是要把一切权力归无产阶级的代表——(略)的,但是为了欺骗和利用资产阶级,团结最广大范围的人民,我们要召集政协会议,政协会议里面必须包括众多的傻瓜,这些傻瓜以为(略)既然讲过新民主主义,那是不是可以给他们制定一部宪法,实施宪政呢。我们先把这些傻瓜骗起来,骗进来成立一个(略),等他们进了以后,我们自有收拾他们的办法~

semi-state是列宁主义的精华所在,semi-state产生了统一战线的概念,统一战线则产生了socialism国家的概念,socialism国家本质上则是统一战线最核心的一部分。socialism国家都是双重的,它的核心是建立在(略)的基础上的,不用说;它的外围,也就是它的表面或者白手套,是建立在爱国统一战线支持的国家上面。爱国统一战线,就是实际上由(略)控制,但是表面上由资产阶级头面人物出头。这个实验的第一步是在远东共和国。Lenin发现,他的实力还不足以完全控制错综复杂的边区,于是就决定,远东共和国应该采取双重政府:形式上它应该有一个资产阶级的国会,而且远东共和国的主要部长是资产阶级人物;同时,一切实际权力,尤其是军队和秘密警察的权力,要掌握在幕后的布尔什维克手里面。
远东共和国旗帜
远东共和国地图

这样,远东共和国可以替他做很多事情。例如,中华民国政府本来是跟列强保持一致,拒绝承认不守规矩的苏俄政府的,但是有了远东共和国以后,中华民国就会跟远东共和国签署条约了,因为远东共和国表面上是一个正常国家。日本人本来奉协约国的命令,干涉西伯利亚事务,日本人来了就不肯走的。怎么样才能把他们赶走呢?Hong军还不一定能打得过日本皇军。这个办法就是,成立一个远东共和国。日本人尽管不愿意跟莫斯科的颠覆分子谈判,但是跟远东共和国的部长会议谈判那是愿意的。如果是苏俄统治海参崴的话,日本人永远不会撤出海参崴;但是远东共和国成立以后,日本就会跟远东共和国签署条约,把日本军队撤出西伯利亚了。日本人一撤出西伯利亚还不到三个月,Lenin立刻就下令撤销远东共和国,因为远东共和国的历史任务已经完成了。外蒙古共和国的寿命比远东共和国要长得多,那是因为中华民国的存在。只要中华民国还能存在的话,那么外蒙古共和国就不能直接并入苏联,它必须做跟中华民国打仗的准备,这就是外蒙古共和国必须存在的理由。你用白手套理论去看国(略)两党后来的历史,那就不用多做解释了,一切都很清楚了。第三种体系就是这样建立起来的。

第四种体系则是冷战结束以后,一方面欧盟在上面建立,作为超国家组织,马斯特里赫特条约(1991年12月9日至10日第46届欧洲共同体首脑会议上签署的条约,包括《欧洲经济与货币联盟条约》和《政治联盟条约》,为欧共体建立政治联盟和经济与货币联盟确立了目标与步骤,是欧洲联盟成立的基础)或者诸如此类的统一货币之类的东西,严重分散了、或者是侵夺了民族国家传统的权力。民族国家传统有哪几大权力呢?战争和外交的权力、财政和铸币的权力、建立独立司法机构的权力。这三大权力由于欧盟的建立都已经受到了严重的侵夺。
▋1992年2月7日,《马斯特里赫特条约》签订,设立理事会、委员会、议会,逐步由区域性经济共同开发转型为区域政经整合的发展,并将欧洲经济共同体更名为欧洲共同体。

欧盟的成员国虽然还有自己的军队,但是实际上它已经不具备单独发动战争或者单独议和的能力了。自从欧元区成立以后,欧洲各国原有的民族国家,尽管原有的架构还留着,但它自己已经没有单独铸币的权力了。如果各国仍然有权单独铸币的话,那么现在,希腊财政危机以后发生的欧洲危机就不可能产生了。司法体系,虽然各国仍然有自己的司法体系,但是欧洲法院和人权法院已经成立,有很多欧洲国家都已经承认,欧洲法院的裁决对本国有约束力。当然这一点仍然非常复杂,例如像是苏格兰就产生了英国式普通法、苏格兰本地的半普通法半罗马法和欧洲法律体系的融合和交错。苏格兰法院是不是应该承认欧洲法院的判决,这是一个非常重要而复杂的司法问题,对欧盟将来的宪法发展是很有参考意义的。

同时,在国家组织的下面,因为国民共同体本身就有先天的弱点,同时在欧盟建立以后,超国家组织已经分去了国家组织的很多权力,实际上客观上是有利于亚国家组织产生的,于是就产生了像瓦隆人(比利时分成三个地区,弗朗德勒(弗莱芒语),瓦隆(法语)和布鲁塞尔(法语以及弗莱芒语),弗朗德勒和瓦隆地区都有要求独立的倾向)、加泰罗尼亚人这样的半国家。照国际法术语来说,它叫做准主权国家实体。像西班牙国会,它就承认加泰罗尼亚是一个国中国。国中国这个话一旦翻译成汉语的话,马上就给人一种不知所云的感觉。什么叫做“国中国”?主权不是绝对的国家。那加泰罗尼亚到底是一个国还是不是一个国?其实这些问题都是汉语本身造成的问题。你从原文和西班牙原有的宪法结构来看,这本身不是矛盾的。state是可以有多重层次的,主权也可以通过修改解释,构成多种不同的半主权或者准主权结构。

这些半主权或者准主权结构,你找具体的例子,就是像波多黎各岛(波多黎各自由邦拥有美国联邦领土地位)、维京群岛(美属维京群岛和英属维京群岛属于未合并领土)或者是像香港这样的地方。你说它是主权国家吗?它不是,但它有自己的宪法结构,有一定的外交权力,照现在的国际法解释来说,它就是一个准主权实体。像维京群岛,它实行的财政货币制度,跟英美都不一样,有很多避税的资本都可以逃到维京群岛。
Flag of United States Virgin Islands
Flag of the British Virgin Islands

像加入美国以前的夏威夷共和国,和现在的波多黎各自治领,它也是这样组织。你说不清楚它到底是不是美国的一部分:从法律上讲,它不是的,它的居民不能选举美国的参议员;但是,他在外交和军事上无疑是由美国保护的,它很有可能加入美国的,但它不仅现在有了自治权,而且还有一定的对外交涉的权力。如果对外交涉最后造成的结果导致了,它不变成美国一个州,而变成马绍尔群岛共和国那样的独立共和国的话,美国也是不能干预的。这种情况叫做准主权国家。

像魁北克也好,像加泰罗尼亚也好,它们将来的前途很可能就是这样的。意大利北部的伦巴第联盟——或者叫北方联盟(1991年成立,主张地区自治乃至独立,影响力正不断扩大)——所要建立的东西也就是这样的。因为意大利的国语实际上是托斯卡纳语,它对于威尼斯人或者那不勒斯人或者皮埃蒙特(意大利西北大区)人来说,跟外语差不多。皮埃蒙特人的语言更接近于法语和普罗旺斯语;而那不勒斯人的语言跟西班牙语反而比较接近。认真地按照德国人发明的那种语言民族主义的道理来说,意大利和德国都是可以进一步解体的。
北方联盟1991年联盟会议横幅

十九世纪欧洲建立起来的民族国家,即使在它的家乡,也不一定会是永久性的体系。因为这件事情,我们可以说这是一个正在发生的历史。正在发生的历史,它就不像是已经发生的历史一样,可以理直气壮地去给它下断语。它是一个已经露出苗头的趋势。露出苗头以后,也就会从世界的核心地带向世界的外围地带不断扩展,影响到整个历史建构。

但是后发地区就是有这样的麻烦:你第一步的建构还没有搞成,第二步已经来了;第二步的建构还没有搞成,第三步已经来了;第三步的建构还没有站得住脚,第四步的建构已经跟着来了。各种不同体系的语言同时在一个话语体系中出现,就产生了两种现象:第一种现象,理论名词不够用;第二种现象,你能够使用的名词全都被人用坏了。像“国家”这个词,它包含着多少种不同的意义,基本上每一个人使用“国家”的时候都是指的不同的东西。这样做的交流效率是非常低的。因为我说的“国家”跟你说的“国家”根本就不是同一回事,我们吵来吵去,其实连对方说的什么话、到底是什么意思都没有搞清楚。

像中国人现在所谓的这个“国家”,至少可以包含着三种意义。第一,帝国,大清所代表的天下国家,一种帝国。它是超民族的、超地方的一种普世价值。为什么你老是听到有些人blablablabla说,西方武断地输出他们的价值观是不好的,而我们朝贡贸易体系从来不武断输出它的价值观。答案是,朝贡贸易体系的主体——北京的朝廷或者什么地方的朝廷,它不是一个国家。它是文明社会的最高领袖,它行使的本身就是一种抽象的、礼仪性的权力。
《天下全舆总图》将中国置于中央

你要说是广东的土豪或者胶州的土豪这些人,他们是一个民族国家的公民吗?他显然不是。他跟皇帝是什么关系呢?他跟皇帝的关系是礼仪上的、象征性的。他们也许会在跟皇帝打交道的时候用一用汉语,说一说儒家经典的语言,还可以说我们家其实不是广东人啦,我们家其实是三国时代跑来逃难的朝廷士大夫的后代啦,这样做跟朝廷说话能够得到比较有利的条件。实际上他自己的那个乡议或者组织团体,用的是不同的语言,行使的是不同的游戏规则。他跟朝廷的关系,既不是国家与国家的关系,也不是国家与人民的关系,而是各自拥有不完整权力的两个政治实体之间的关系。这种关系比较接近于民族国家以前那种多元权力结构,尽管从复杂度来说它赶不上欧洲中世纪,但是毫无疑问已经超出了现在我们想象出来的那种绝对主权国家体系。

我们今天讨论国家的时候,实际上是包含了三种概念:第一种概念就是明清所代表的那种帝国概念;第二种概念就是蒋介石企图建立起来的那种中华民族的观念,当我们讨论国家主权不容侵犯、国家主权是绝对的、不得干涉内政的时候,实际上是蒋介石借尸还魂在你的大脑里面替你说话;还有第三种概念,就是(略)的那种统战式的国家概念。这种国家概念的实质是欺骗。我们希望,你们跟我们打交道的时候把我们看成是国家,但是我们自己绝对不把自己看成国家。

这不是开玩笑。就是说是,我们制定的法律不像是所有国家的法律那样是能够行使的。你们自己以为你们是(略)的公民,根据(略)宪法实施某种权利;但在我们看来,(略)本身就是一个白手套,(略)宪法这个东西就是欺骗你们这些资产阶级的一种东西。我们需要利用你们去对付香港资产阶级或者美国资产阶级的时候,我们暂时容许你根据(略)宪法,想象你有(略)的公民权利如何如何;但是在我们没有敌人或者敌人变得不再可怕的时候,我们就要让你们明白,(略)宪法像废纸一样的不值钱,你自己真正的身份实际上是一个已经被用完了的统战对象,即将恢复你作为阶级敌人的本色。这个问题才是(略)一切宪法问题的根本。因为大家用“国家”或者“(略)”这个词,都包含了各种互相矛盾的概念,所以本质上讲就是自说自话,各自都在运用自己一厢情愿的逻辑,去想要迫使别人按照自己希望的方式去理解(略)。这样的讨论当然是不会有结果的。

如果你,比如像很多人不断讨论的那样,为什么日本能为什么(略)不能?其实答案很简单,因为日本在近代跟西方国家接触了以后,由于自身的条件比较单纯,各种有利,它比较容易地建立了西方欧洲式的民族国家那种体系。而大清帝国呢,它像俄罗斯帝国、奥斯曼帝国、莫卧儿帝国一样,它涉及的地域太大,种族和地方分歧度太大,它就不像韩国那样比较小的实体那样,可以轻易转型为民族国家。韩国为什么能成功?就因为它比较小。你不要以为韩国人相比起吴越市民来说有多大的优越性。不要说明清以前的情况,就是在三十年代,蒋介石那个时代,朝鲜的革命党人跑到中国来的时候,他还觉得苏州、上海一带,比起朝鲜来说那不知道是繁荣昌盛多少的,跑到这儿来简直是乐不思蜀的感觉。不要说别的,就算是日本人,像是谷崎润一郎(1886-1965,日本作家,代表作《细雪》。1918年,他经朝鲜来华,开始了长达近两个月的中国之行,历访了沈阳、天津、北京、武汉、九江、南京、苏州、上海等城市)那种文人,他跑到大连来溜达一圈,他就觉得日本本土实在是太土鳖了,大连先进得跟欧洲一样,日本人又穷又土鳖。当时的格局仍然是这个样子的。

如果你要用韩国或日本那种已经建立起来的民族国家的逻辑来考虑(略),那你就不要问为什么日本能(略)不能,那你就要老实承认,因为人家的民族国家已经建立起来了,你还没有建立起来。而且不光是没有建立起来的问题,而是,你还没有建立起来,人家的民族国家体系已经开始过时了。这后一点是最可悲的。比如说我要学微积分,老师给别人讲微积分,他已经学会了我还没有学,这不要紧,他今年学会了,明年我也学,大不了十年以后我也就学会了。但是你要是面临着这种情况,人家学会了,刚刚毕业了,你还在报名阶段的时候,学校已经不讲微积分了,而且微积分已经作废了,这种情况下你会面临着怎样复杂的情况呢。

现在有一种很常见的说法,就是说,北伐以后我们犯了多么严重的错误,以前在梁启超和胡适那个时代,我们讲西方的立宪自由还讲得很好的,为什么到三十年代以后,我们又有很多人,像丁文江那些人讲新型的专制国家,为什么我们这样开倒车、走回头路呢?其实这个道理是很简单的。北伐以前中华民国的知识分子,他们是有老师的,他们学的是谁呢?他们学的是十九世纪的欧洲知识分子,他们脑子里面的世界,就是欧洲民族国家的世界,这个世界是日本人已经学到了手,但是俄国人、土耳其人和大清帝国都没有学到手,只要我们把这些东西学到手了,我们不就跟欧洲人一起先进了吗?要国会、要选举、要宪法、要中华民族、要联邦共和国、联省自治,这些东西都是十九世纪欧洲的逻辑。丁文江的时代,他们面临着的是什么呢?他们面临着的是欧洲自己已经变了。那已经是第一次世界大战以后的欧洲、布尔什维克时代的欧洲,社会民主党的国旗队和布尔什维克的枪手和纳粹的冲锋队在大街上打来打去。
▋一战促使了女性地位的大大提高,女权主义也在战后开始空前盛行,图为一战中的英国女工人。

你要设身处地,按照十九世纪资产阶级的想法来考虑这个问题。十九世纪资产阶级的想法是什么样呢?修身,齐家,治国,平天下。你首先要有能力照顾自己,然后才能有能力照顾社区,然后才有能力照顾国家。如果你小子连自己都养不活,连自己家都顾不好,你凭什么去治理国家呢?所以治理国家最先考虑的是,你必须是资产阶级,你必须要有钱。我们设计一个绝对客观、谁也不可以侵犯的标准:财产权标准。有产阶级就是国家本身。所以你要明白,Marxist-Leninist者说民族本质上是一个资产阶级概念,这话是没有说错的。国家这个东西照原始定义是剥夺无产阶级的。无产阶级你要想参与国家,你首先要能够挣钱养活自己。你连养活自己都做不到,你就不用替国家考虑了,你已经充分证明了你没有资格管国家的事情了。如果你有能力管国家的事情,你至少应该做到能够把你自己老婆孩子养活得了吧。你老婆孩子还要靠老板替你养活,你凭什么说要去治理国家的事情。这就是他们的逻辑。

普选制打破了这种逻辑,然后就导致了资产阶级政党所完全没有想到的现象,武装的暴民在街上相互厮杀了,群众性政党开始产生,自由主义政党落了下风。自由主义政党是讲理的政党,它假定自由主义的成员都是足够聪明的人,可以通过讲道理来解决问题。但是无产阶级参政以后就出现了一种新的你想象不到的做法:无产阶级政党,它可以把群众组织起来,组织一群相互掐架的集团,组成红卫军和白卫军,然后按照Lenin同志那种办法,我们用兵去包围国会,然后看看你小子敢不敢不听我们的决定。Lenin派兵包围立宪议会以后,他给立宪议会提出了什么样的条件呢?立宪议会要把自己改组成为一个专业研究机构,而且这个专业研究机构只限于一个研究范围,就是根据布尔什维克提出的要求,研究俄罗斯应该怎样转型为socialism国家的问题,除了这个问题以外,你们什么也不要研究,你就乖乖去研究去吧~当立宪会议表示说,这种研究方法跟国会的宗旨不合的时候,Lenin就派兵冲进国会把他们统统赶走了①。这种做法很快就被其他人学会了,比如说墨索里尼那个进军罗马就是这种办法。他带领着他自己的黑衫党的党徒,开进罗马去包围国会。希特勒的做法也是这样的,只不过德国的情况是更复杂一些。

1、1918年年初,俄国立宪会议召开前,议会选举投票结果揭晓:在总共707个席位中,布尔什维克得到175席,占24.7%,而社会革命党得到410席 (其中左派社会革命党占40席)。会前,Lenin知道投票结果对己方不利,已经打算 “用武力更正票箱”。开会当天,布尔什维克代表要求立宪会议把权力交给苏维埃,多数立宪会议代表拒绝了这个要求,他们在暴力威胁下一直坚持到次日凌晨4时,终被布尔什维克调来的军队驱散。俄国的议会实验就这样结束了。

(略)有(略)的武装人员,社会民主党有社会民主党的国旗队,纳粹有他自己的冲锋队。三个群众性政党的武装人员在大街上大打出手。它们任何一个的实力都比德国国防军要大得多。我们知道,凡尔赛条约以后,列强限制德国的军备,德国国防军总共只有十万人。纳粹的冲锋队和社会民主党的国旗队,从理论上讲那是有几百万人的。为什么有几百万人?因为它们是工人阶级政党。社会民主党说我是Marxism正宗,我代表工人阶级,德国有几千万工人,从中选出几百万精英分子当民兵有什么不可以呢?纳粹也说,我们是民族社会主义者,我们当然也要选出我们自己的民兵。(略)人呢,论民兵数目比较少,但是搞秘密活动则比纳粹党和社会民主党都强。但它们的共同点是,它们都是群众性政党,它们都要用武力,通过打架来说话。
▋1934年纳粹主义展览场,从外观就可以看出希特勒同时对种族主义和工人阶级斗争的宣扬

在这种情况下,极少数资产阶级政党怎么办呢?他们在街头是一点势力也没有,因为他们从来没有做好打架的准备,一旦有人打架的时候他们就狼狈逃跑了。这种事情在远东的对应现象就是,梁启超的保皇党开会的时候,张继(1882-1947,国民党元老)他们就带着国民党人去砸场子。砸场子的结果是梁启超带头逃跑,在座的所有绅士都以最快速度逃跑了。他们从来没有做好打架的准备,而且他们手下也不像是革命党那样养着大批的日本浪人可以打进来。在这方面,远东跟欧洲的主要不同就是:欧洲的群众性政党打架的时候主要靠自己人;而远东,至少在大陆这一方面,群众性政党,国民党和(略)要打架的话,主要都依靠日本人和俄国人,无论是金钱还是武力都是要依靠国外输入的。那是因为他们出于各种现在不方便讲的原因,他们所在的这个社会在战斗力和组织力方面是极其差劲的,因此他们不可能像欧洲工人阶级那样组织自己的武装。要想有武装,最有效的办法还是输入卢布,从国外输入武装力量。

这种逻辑一旦实施的话,旧有的自由主义所设想的那种国会政治就变得不可能产生了。新型的国家要重新产生稳定的宪法结构,那是需要经过长期博弈的。长期博弈的结果就是产生了我们现在所谓的共识政治,社会民主党为一方、资产阶级为一方的一种政体,国家只是一种分配社会福利的机构。现在我们看到这个体制,觉得它好像是相当稳定的,但它在第一次世界大战以后刚刚转型的时候,也是充满着流血和混乱的。德国也好、意大利也好、法国也好,整个欧洲大陆都是血雨腥风,赤卫队和白卫队这样的私人武装集团不断在街头打打杀杀。当时老一辈的资产阶级人士和体面人士看到这种情况,那就像现在的人看到黎巴嫩一样,本来以为是第三世界国家、叙利亚才会有的内战局面,居然在我们欧洲的街头上上演了,但我们也不知道应该怎么办。

不仅是欧洲大陆,甚至是英国人,在1926年大罢工(1925年,英国煤炭工业严重衰退,1926年4月,矿工工会发动了全国煤矿工业大罢工。5月3日,英国工人展开了英国历史上第一次统一的全国总罢工。随后,英国的交通运输陷入瘫痪。工人罢工委员会、行动委员会、纠察队和工人自卫队等上街活动。1927年,议会通过《劳资争议与工会法》,宣布总罢工和一切同情性罢工为非法,禁止组织群众性的罢工纠察队)的时候,都出现了这样可怕的局面,工纠队像是人民民主专政一样掌握了职权,任何一辆私家车想要开出去在大街上遛弯儿的话,他都要在车上贴一个牌子:经罢工委员会准许。罢工委员会是什么呢?按照十九世纪法律的规范,它就是一个赤裸裸的犯罪集团。罢工委员会怎样才能执行罢工?他必须实施打倒工贼的权力。什么叫打倒工贼?就是说是,他不准你上工。如果有一部分人上工另一部分不上工,那他怎么搞罢工呢。人心不齐,总会有一部分人意见不同的。所以必须有工纠队。工纠队要对全体工人实施强制,不准工贼私人上工。一旦实行罢工以后,罢工委员会的权力就很容易扩展到整个社区上,它会对整个社区实行一个类似戒严的权力,你们资产阶级要是在罢工正在进行的区域开着你们的私家车上街游玩的话,那是一件相当危险的事情,工纠队很可能会砸你的车的。
1926年大罢工迫使英国派坦克上街维护治安

现在(略)的启蒙派,有很多人是头脑极其天真的,他们每一次看到西an斯坦,哦对不起是西an,西an的某些暴民砸了日本车以后,他就痛心疾首地讲起国民性来了,哎呀,(略)的国民性太差劲了,欧洲人和日本人就没有这样的事情。我得提醒你一句,欧洲人和日本人跟大家其实都是差不多的。如果表现得不同,那是因为你的发展阶段不同。欧洲人,哪怕是英国人,在1926年大罢工的时候也是这个样子的。在1934年维也纳街头,双方之间的枪手是比hu南或者是西an的任何暴民都要打得厉害的(1933年,奥地利社会民主党与执政的基督教社会党矛盾激化。1934年2月12日,警察进入社会民主党林兹党部搜查。当周,社民党的武装势力在维也纳和其他工业地区抵抗警方。政府调动军队镇压。内战一直持续到2月16日,最后社会民主党被认定为非法,多数领导阶层遭到逮捕有数百人死亡,近千人受伤,而其余的社会主义者都纷纷逃离国家;基督教社会党继续掌权,打击曾经与社会民主党合作的组织如工会)。我们不要特别忏悔说是,(略)杀了多少人,(略)多么卑贱,大家不要忘记德国社会民主党在二十年代的柏林街头杀了多少人,芬兰和瑞典的社会民主党是怎样喝醉了酒、扛着大棒去砸布尔什维克在当地的党支部的。你要说这种做法一定跟(略)砸保皇派的支部有多少区别,也不见得。

实际上的情况是,你不能够搞什么不公正的对比,你不能用我的宪法结构不稳定的时期去直接对比别人宪法结构稳定的时期。任何一个体系,在它自己宪法结构进入相对稳定期的时候,它都会显得是非常体面而有秩序,秩序非常好,仿佛非常自由。但是,在旧秩序和新秩序交替的时期,它必然会充满着混乱和暴行的。在任何一个地方都是这样,欧洲并不例外。欧洲人在旧秩序和新秩序交替的时间也是充满混乱的。

至于它的好处在哪里呢?就是它的旧秩序和新秩序的交替,经过一段时期的博弈以后,能够达到新的平衡点,在新的平衡点上,它又显得像是很绅士、很体面的样子。而你这方面呢,你还没有达到新的平衡点,而且新的平衡点很难达到。它为什么能达到新的平衡点?与其说是因为它自身有种种优越性,不如说它是世界秩序的中心,它本身只存在着后浪推前浪的问题,新的博弈达成了新的平衡点以后,秩序就可以稳定下来,它不大考虑横向干涉的问题。而你处在世界体系的边缘地位,旧的体系还没有建立起来,新的体系就开始砸旧的体系了。外来的秩序不断输入,而且不同时代的秩序不断发生作用,任何一种秩序都没有办法充分伸张自己的正义。结果,每个人都有道理,而每个人又都没有道理。因为不同的人是按照不同的秩序行使自己的权利和义务的,这样自然要造成矛盾和混乱,这是过渡时期的特权啊。

▋补充:在本系列(一)中,阿姨论述道“全世界现在的互联网有几十个根,其中有十个都在美国,而且都在加州。”有读者补充说“全世界就十三根根服务器,一个主根,十二个辅根。辅根除了两个在欧洲,一个在日本,其他全在美国,但主根在弗吉尼亚,并不是在加州”。

(四)

你如果像德国犹太人或者XX时代的黑五类一样,对自己的共同体身份有错误认知,那么,这无非是使别人在整你的时候成本更低,而你自己在博弈当中处于更加不利的地位。

像法国大革命时期就有这种情况,法国贵族跟着御弟(路易十八,1755-1824,路易十六的弟弟,1791年成功逃往国外,拿破仑失败后回国继位)跑到国外去了,然后带领着外国兵来打法国。然后革命党就说,你们卖国;而保王党则骂他们说,你们弑君。保王党的逻辑就是说,什么是法兰西,法兰西就是法兰西国王,法兰西国王被你们抓起来了,御弟跑到了国外,御弟就是合法继承人,我们跟着合法继承人来打你们这些乱臣贼子,这是再正义也不过了,你们才是叛国者。而革命党则说,不对!我们是效忠国家不效忠国王的,国王只有忠于国家才是国家领袖,不忠于国家,即使是国王本人也可以审判的,我们把国王本人杀死也完全符合新时代的道理。

他们谁有理谁没理呢?都有理都没理。按照封建的伦理体系,那么你当然应该忠于国王,如果本国的暴民把国王都抓起来了,这还了得,你当然应该带着国王的三亲六戚回来替国王报仇,这些三亲六戚是普鲁士国王和奥地利皇帝,这无关紧要的,因为我们的政治共同体本来就不是按照血缘和地缘划分的,而是根据相应的效忠、契约而建立起来的。按照民族国家的道理来说,你们这些人就不对了,法兰西国王为法兰西效力的时候你们尽忠国王是对的,法兰西国王不为法兰西效力的时候,你们再跟着国王跑,你们就是叛国了。你是弑君者;不对!我们不是弑君者,我们是爱国者;不对!你们不是爱国者,你们是弑君者……这样的吵法能吵出结果来么?不可能的。因为双方实行的是不同的游戏规则。

法王路易十六被处决

中国近代的情况也是这个样子。建立满洲国的那些遗老遗少,他们忠于中华民国吗?不对,中华民国是大清的敌人,他们忠于大清皇帝。蒋介石说(由于众所周知的原因,此处有所删减,本文其他删减之处也皆以“略”替代,请读者们原谅。完美版已推送给vip读者。订阅冬川豆会员,请加小编ID:dongchuandouclub)不讲道义,(略)为什么要跟你讲道义?它是TG国际的支部,它本来就是要推翻中华民国的。你凭什么会认为它参加这个民国就应该效忠于你、它应该对你讲道义?什么人能对什么人讲道义?我们如果是同一个共同体的成员,我才对你讲道义;如果我们本来就是敌对的,那我为什么要对你讲道义?法兰西人如果杀了法兰西人,那是犯了谋杀罪;他杀了德国人,那是战争的一部分。如果我对自己的定位是法兰西的国民,那么我不能杀本国的资本家,但是可以杀普鲁士人;但是如果我对自己的定位是(略),那么我就应该跟德国的无产阶级一起杀本国的资本家了。我杀本国资本家,这不是犯法,这是一个战争行为,这不是不讲道义的。我打你,因为你是属于敌对阶级的成员。

在这方面,中国现在的知识分子把概念给搞混了,他们总是用不同的概念来考虑不同的共同体的问题。我们必须说,(略)本人对这方面的态度还比较清醒。他有句名言叫做:革命的首要问题是什么?谁是我们的朋友,谁是我们的敌人?(《中国社会各阶级分析》,1925年12月)这句话翻译成政治学语言就是:第一重要的事情是要划清共同体的边界,谁是你的自己人谁是你的敌人。如果你按照蒋介石那种方法划分共同体边界,那么(略)就是乱臣贼子了,但(略)本人却把你当阶级敌人了。大家说(略)是搞大屠杀什么什么的,是多么多么野蛮,但是不要忘记,这是一个战争权力的问题。他们杀的谁呢?他们在hu南道县把有些在土改时期没有杀完的地主、富农、黑五类或者其他什么什么阶级异议分子给杀了(1967年7月至10月),他们不是无缘无故、见谁杀谁的野蛮人,他们杀是有目的、有针对性的,他们杀的就是(略)建国的时候没有杀完的那些阶级敌人,这是阶级战争的一部分。

你说中国人特别野蛮或者中国(略)特别野蛮,很好,那么我问你一句,芬兰的白卫军杀本国的工人纠察队的时候(十月革命后不久,芬兰脱离俄国独立。1918年初,芬兰赤卫队与原驻芬俄军夺取赫尔辛基,解散议会,控制了芬兰南部广大区域,建立红色政权。芬兰政府在德国支持下组织白卫军发起反攻,驱逐了红色势力。此后,芬兰反赤运动兴起。1929年末至1932年的“拉普阿运动”中,人们大规模搜捕共党嫌疑者),他曾经手软了么?你如果把这方面的材料挖出来就清楚了。在维也纳的街头,基督教社会党人杀社会民主党人和纳粹党人的时候(一战后奥地利独立,主要政党基督教社会党和奥地利社会民主党都有自己的军事组织,时常发生冲突。1934年2月,基督教社会党党军在林茨市搜捕社会民主党党员时,双方爆发冲突,很快波及其他城市。军队介入后逼使社会党军投降。事件造成数百人死亡,近千人受伤。奥地利的社会主义者纷纷外逃,而基督教社会党继续掌权, 打击曾经与社会民主党合作的组织如工会),他曾经手软了么?社会民主党的枪手在柏林杀斯巴达克团的时候(1918年,德国爆发十一月革命,德意志帝国崩溃,社会民主党人接管了政府,12月,左派社会民主党人(斯巴达克团)成立德国共产党,于次年1月发动革命浪潮。社会民主党政府在自由军团的支持下成功将革命镇压,德共领袖李卜克内西、卢森堡被杀),他曾经手软了么?他没有。他不能手软。如果他手软的话,那么将来就不会有他的共同体了。
芬兰白卫军处决赤党分子
白卫军纪念碑

只要共同体本身的边界还没有弄清楚,模糊概念是没有好处的。模糊概念只会造成一些统战对象式的上当受骗者。你以为你是,但你其实不是。像德国犹太人就是这样的,我以为我是德国人,我虽然是犹太人但我也是德国人啊,我人在德国不走。但是在希特勒看来,你根本不是德国人,你就是敌人。你以为你是自己人,人家把你当敌人,那杀你的成本当然很低了。(略)杀死的那些人是什么呢?就是上了当的统战对象。他以为我是(略)人,(略)也是中国人,你们何至于来杀我。在(略)看来,你明明是阶级敌人,你还冒充自己人,混入革命队伍,那比赤裸裸的敌人还更加可恶。所以(略)的投降将领我不一定会杀,你们这些自以为是革命功臣的老革命,不杀你是绝对不行的啦。

所以这里面的问题就是:一个人首先要搞清楚自己生活的时空位置,你是不是处在一个游戏规则已经稳定的时代。不仅在我们所在的(略),即使在人类整个历史上,可以说始终是治日少而乱日多,博弈正在进行的时间比较多,而博弈已经稳定的亚稳态是比较少的。这是自然而然的。如果你把世界看成一种达尔文系统,那你就可以看出,达尔文系统的大部分时间和地点都是处在激烈的冲突之中的,极少数相对稳定的时间段和地区,是在此之前长期博弈达到的平衡。但是破坏平衡是很容易的,维持平衡则是很难的。每一次当你以为现在的平衡已经建立,可以千秋万代的时候,新的不平衡因素又要出现。斗争是永恒的,而平衡却是暂时的。

在这种情况下,如果你真想清楚地认识世界,你就得承认,最好是不要把那些你认为应该建立但是实际上没有建立、而且不大可能建立的秩序,当作你所在世界的真实语言。应然和实然是完全两码事。个人伸张个人正义的结果,一般来说就是延长了博弈和过渡期,使新的亚稳态达成的时间延长。在这个博弈期内,一切都是非常混乱的。你如果像德国犹太人或者(略)时代的黑五类一样,对自己的共同体身份有一个错误认知的话,那么,这无非是使别人在整你的时候成本更低,而你自己在博弈当中处于更加不利的地位。

同时,在新旧游戏规则交替的情况下,那就像陈寅恪教授所说的那样,总有人两面占便宜,有人两面吃亏①。新旧游戏规则对不同的人有不同的义务,像在法国大革命的时期,国王来的时候我就说我根据封建主义原则,我效忠国王;共和国来的时候,我又可以说,我根据民族国家的原理效忠于国家。这样你就两头占便宜了。像富歇(1759-1820,大革命时为雅各宾派,投票赞成判处路易十六死刑;1794年策划热月政变,推翻罗伯斯庇尔;1799年担任警务部长,1804年拿破仑称帝后成为警务大臣,1815年拿破仑下台后成为临时政府首脑,迎接路易十八)那样的机会主义者就是这么干的。你也可以恰好相反:在国王快要被杀的时候你可怜国王,说国王他其实不是想要对抗法兰西国家,他只是按照过去的老规矩办事,不懂新规矩而已,于是你就变成反革命了,你可能和国王一起被杀掉;然后共和国垮台以后,你又站出来说,共和国那些人也并不是一帮嗜血的弑君分子,他们只是想要引入一种新的秩序,然后你就可能被愤怒的保王党人私刑处死。这就叫做两头吃亏。你用这种原则来考虑一下近代东亚的历史,我想我就不用举出具体的人名来了,上面这两种人写满了历史,大家可以自己按图索骥去查查他们各自的身份,看看他们干了什么事情,他们是怎样两头占便宜或者是两头吃亏的。

1、《元白诗笺证稿》:“纵览史乘,凡士大夫阶级之转移升降,往往与道德标准及社会风习之变迁有关。当其新旧蜕嬗之间际,常呈一纷纭综错之情态,即新道德标准与旧道德标准,新社会风习与旧社会风习并存杂用。各是其是,而互非其非也。斯诚亦事实之无可如何者。虽然,值此道德标准社会风习纷乱变易之时,此转移升降之士大夫阶级之人,有贤不肖拙巧之分别,而其贤者拙者,常感受苦痛,终于消灭而后已。其不肖者巧者,则多享受欢乐,往往富贵荣显,身泰名遂。其故何也?由于善利用或不善利用此两种以上不同之标准及习俗,以应付此环境而已。”

东亚的问题在于什么呢?它博弈的稳定点很不容易达到。一方面是负责给国民提供知识的知识分子自己都头脑混乱,知识分子自己就没有搞清楚自己想要什么。中华民族是梁启超发明的,但是中华民国一成立,他马上就变了好几次,每一次都是为了现实政治的需要改变他的政治逻辑。国民党起家的政治逻辑本来是解构中华民族,把满蒙赶出长城;但是他自己一旦有了机会以后,他马上就把中华民族的衣钵重新捡起来,说所有的各族群都仅仅是中华民族的一部分。(略)在这方面的机会主义行为我就不用再介绍了。但共同的特点是,所有的知识分子都企图利用自己掌握笔杆子的权力为自己牟利,故意制造模糊概念。知识分子尚且如此,政治家就更不用说了。这是主观条件。

欧洲知识分子就比较诚实。可以说,不仅仅是欧洲,大多数地方的知识分子是相对来说比较诚实的。你看十九世纪欧洲的情况,大体上来讲,如果他们是主张民族国家的,他们一生很少会改变主意,主张封建主义的人也很少会改变主意。这样做至少有一个好处:边界比较清楚,认同比较清楚。我支持你,到底我是为了什么支持你呢,我想要得到什么,不想要什么,这一点至少是人人都能够看得清楚。人人都能够都看得清楚,边界清楚,那么博弈的机会成本就降低了很多。边界不清楚,就等于说是,人人都是骗子,而且人人都把别人当成骗子,这样博弈的成本就自然高了很多。

另外一个关键问题是什么呢,就是一个基本盘的问题。你要处理的基本盘越大,你需要的时间就越长。东亚这个基本盘,按照规模上来讲,跟日本和韩国不对应,跟英国和法国不对应,它相当于是整个欧洲。你要让整个欧洲从一种结构转变到另外一个结构,你就会发现,它自己也要花一百多年时间的。从封建主义的结构转到民族国家的结构,从民族国家结构转到第一次世界大战以后的全民政治的结构,再从冷战以后这样转,每一次转,时间都是上百年啊,如果以整个欧洲为单位就是上百年。但是你不拿整个欧洲比,你只跟一个具体的国家比,你只跟荷兰或者波兰这样的小国家比,这些小国家论体量来说,只跟韩国或者台湾相当,跟整个大清的版图是没法相比的。

你如果把大清跟整个欧洲比,或者跟整个拉丁美洲比,你就会发现,其实大清的表现并不是特别差。欧洲人从封建主义转向民族国家体系,也是经历了一百多年时间,其中爆发了多次战争。对于西欧的国家来说,是经历了大革命和法国革命的残酷战争以后才建立的。对于东欧国家,大概需要经过第一次世界大战、第二次世界大战和冷战这三场浩劫才能够建立得起来。以这些浩劫的标准来比,从辛亥革命、北伐战争、抗日战争、冷战,直到现在的东亚,它付出的代价并不算高。根本上讲,时间上来讲还没有东欧来得长,流的血也并不是更多。

当然如果你一定要抬杠说,我为什么不跟美国人比,美国人没有流多少血。但是我们不要忘记,美国的前半部分在欧洲。美国历史的后半部分之所以显得如此的温和和不用流血,是因为流血的部分早已经在英国流够了。英国人在十六世纪、十七世纪流血的时候,按照它自己的标准也是极其残忍的。大家不要忘记当时的英格兰王国总共也就只有几百万人口,它为了宗教战争和宪法战争牺牲了全国十分之一的人口。但是“全国”这个词肯定是错误的,在革命和战争以前,还没有什么英格兰王国,也没有什么大不列颠联合王国,只存在有英格兰国王和许许多多的诸侯,是革命和战争造就了一个统一的英格兰王国的概念。
Cranmer’s martyrdom, from John Foxe’s book (1563)

同样的道理,法兰西民族是法兰西革命所造就的,波兰民族是缔造波兰民族的历次战争所造就的。不是说先有了波兰民族或者法兰西民族,然后才有民族的精英分子通过革命和战争的种种手段,把他们解放出来了。那是骗人的。实际上发生的事情是,战争和革命在原来还没有波兰民族和法兰西民族的地方,把这些人造就成了波兰民族和法兰西民族。Lenin之所以要造就无产阶级新人,他就是想模仿这个过程,认为旧的共同体不好,我们可以通过革命和战争把旧的共同体打烂,用同样的方法,用新的阶级共同体代替旧的民族共同体。

这才是二十世纪历史真正的关键所在,其他的一切其实都是浮云和枝叶。而由于你误解了体系本身的性质和博弈逻辑,用一连串多愁善感的废话去解释这些浮云和枝叶,结果就把本来很清晰的事情都给解释乱了。有很多事情一落到具体实例上,就能够讲得很清楚了。像德王(德穆楚克栋鲁普亲王,1902-1966,1908年袭札萨克多罗杜稜郡王爵职,1913年北洋政府授为札萨克和硕杜稜亲王,1919年执掌旗政。1936年德王任察哈尔蒙政会副委员长,2月10日在日本关东军支持下成立蒙古军政府任总司令、总裁。1937年10月27日,在归绥市召开“第二次蒙古大会”,宣布蒙古自治,成立了“蒙古联盟自治政府”)这种人,他是什么人呢?他恰好就是波兰爱国者这样的人。

波兰爱国者发动革命的时候,普希金这样的文人就站出来说,波兰人是斯拉夫人的叛徒①。斯拉夫人是抵制欧洲理性主义和功利主义的唯一匹敌;而欧洲人——俄国人所谓的欧洲人呢,照他们看来就是市民阶级市侩的产物,一切按照功利和契约的方法来解决。宪法是什么?宪法不就是一个契约么。谁签署契约呢?契约的本质不就是合同么,商人跟商人才会签署契约,斤斤计较的小市民才会跟斤斤计较的小市民签署契约。好朋友跟好朋友之间那是不用签署契约的啦,大家是哥俩好,神秘的俄罗斯灵魂,你的也是我的,我的也是你的。如果我要跟你签署契约,那就是我把你当外人了,这是多没礼貌的事情(俄国“保守主义者”的《路标文集》里有一首著名的诗:“因为是有机论者,我们完全不要法律的健全理智这一狰狞的恶魔。俄罗斯大自然如此广袤辽阔,何须爬进法律原理这一狭窄的躯壳?”)。

1、在尼古拉一世派俄军镇压波兰1830-1831年起义,引起英法等欧洲国家舆论谴责的时候,普希金连写了三篇反波兰的诗:《给诽谤俄罗斯的人们》、《波罗金诺周年纪念》、《在这神圣的坟墓之前》。他在诗中说,“这是一场用不着你们来调解的为命运所决定的古老的家庭纷争……你们嘴上很厉害,但干起来试试看!难道俄国沙皇的谕旨已经不起作用?难道我们要同欧洲重新争论?难道俄国人不再善于取胜?”他在长信《致恰达耶夫》(1836)中说:“我们有自己的特殊的使命……她那广袤无边的领土化解了蒙古人的侵略。……由于我们受苦受难,天主教的欧洲才能排除种种干扰从而得到大力发展。……要说我们历史贫乏,您的意见我是绝对不能同意的。……彼得大帝一个人就是一整部世界历史!把俄国置于欧洲门槛上的那位叶卡捷琳娜二世呢?把我们带进巴黎的亚历山大呢?……地老天荒我也不会换一个祖国,除了我们祖先的历史、上帝赐予我们的历史之外,我不会再有另一部历史。”
▋1793年俄罗斯帝国与普鲁士王国将波兰第二次瓜分的瓜分条约

欧洲人之所以签署契约,那说明什么?说明欧洲的君主和他的人民之间是商人和商人那种唯利是图的关系,签署宪法充分证明了他们的道德水准不好。而我们东正教的人是什么样呢?沙皇就是人民,人民就是沙皇,沙皇和人民之间有超验性的联系,是息息相通的,沙皇不可能违背人民的利益,因为沙皇就是人民本身。如果你要沙皇签订宪法,那么实际上就是要割裂沙皇和人民之间本质的和神秘的联系,这样做是不好的。你要按照欧洲那样让波兰建立国家,实际上就是要割裂斯拉夫民族这个神秘共同体,把它们变成欧洲式的世俗国家,这不是进步,而是倒退。“沙皇就是人民,人民就是沙皇”这个理论今后大家会听得到的,早晚会有人告诉你们,人民就是(略),(略)就是人民,中国就是(略),(略)就是中国。而且这种理论并不是胡说八道,除了用这种方法以外,不可能用任何其他方法把我们现在制造的这个中国粘在一起。

现在制造的这个中国是怎么样产生的呢?它是大清瓦解以后收拾残局的产物。我们不要相信辛亥革命能够推翻大清帝国,革命党是推翻不了大清帝国的。辛亥革命真正发生的情况是什么呢?是南方各省的士绅阶级和北京的朝廷无法达成一致,真正发生的事情是大清的解体而不是革命党的胜利。大清解体以后,各省就把自己的收入据为己有,建立了自己的军队,因此继承大清的政权难以建立。在这种情况下,大清很可能会像是西班牙帝国解体以后,美洲建立一系列分崩离析的国家。

但这个时候袁世凯和朱尔典(John Newell Jordan,1852-1925,1906-1920年为驻华公使)出来了。为了方便跟列强交涉起见,为了避免发生更大规模的战争,列强给袁世凯贷一笔钱用来收拾残局,然后大清帝国留下的各个地方好歹达成一个协议,这就是五族共和的中华民国。五族共和的中华民国像阿富汗的卡尔扎伊政府一样,是依靠外国贷款支持起来的。没有善后大借款(民国成立之初,财政异常困难。1913年,北洋政府向英、法、德、俄、日五国银行团借款二千五百万镑),不可能有中华民国。无论是南方各省也好,北洋各地也好,还是满蒙各地也好,他们之所以认袁世凯,唯一的理由就是袁世凯有办法从外国人那儿借到钱。地方上的收入已经被各省截留了。
▋1913年中华民国政府向五国银行团善后大借款中的,505法郎公债券,由东方汇理银行(Banque de L’Indo-Chine)代理发行,棕色印刷,公债券上的签署人为北洋政府总理兼财政总长熊希龄、驻法公使胡惟德。

大清是怎样出现的?我们可以用简单粗暴的方法来说,大清是满蒙贵族骑士提供军备,同时江浙士大夫提供粮饷的一个结合,它体现为大运河,满蒙贵族负责打仗,江浙士大夫阶级负责出钱,于是就把大清帝国给维持起来了。洪杨战争以后发生的一系列变化是什么呢?满蒙贵族变得不能打仗了,于是南方的士大夫就不愿意替他们出钱了,解体是必然的。新军是南方的士大夫自己筹钱办出来的,他们不需要满蒙贵族,而满蒙贵族也不愿意受南方的统治,这种情况下谁能实施统治呢?就是能够从外国借钱出来的人。借钱维持中华民国政府,中国就是一个国家;不借钱,那么各地的军阀和实力派人物就把它分割了。

这个逻辑其实跟十九世纪的摩洛哥和现在的阿富汗是一样的。阿富汗为什么存在?因为列强愿意派一支维持和平的部队去,愿意给卡尔扎伊政府借钱。卡尔扎伊就是阿富汗的袁世凯。他为什么能够存在?因为国际社会认为,阿富汗在联合国有一个席位,跟阿富汗打交道不能没有一个中央政府。没有一个中央政府,我们各自去跟塔利班打交道、跟基地组织打交道、跟伊斯兰国打交道、跟普什图部落(阿富汗南部和巴基斯坦西部的主要民族)酋长打交道,这太麻烦了。而且他们使用的语言和习惯法我们也不懂。我们最好到喀布尔去,喀布尔象征性的好歹还有一个外交部,虽然这个外交部签署的条约连喀布尔城门都出不了,但是总比连一个外交部都没有要好一点。既然有了那么一个政府,他自己又在喀布尔城外收不到钱的话,我们好歹,各国列强凑一点钱来给你,然后他又是个穷地方,我们自己稍微省一点,比如说把洛杉矶的泊车费给你省下来,就这样给你施舍一批美元,然后你们喀布尔政权就可以建立起来了。

如果有朝一日,塔利班或者伊斯兰国打进了喀布尔,他可以毫不犹豫地说,喀布尔政权就像袁世凯和北洋军阀的政权一样,是一个代表帝国主义的政权,这是毫无疑问的,铁证如山的。没有帝国主义的经济支援,它连公务员的工资都发不出来。在帝国主义支援不到的地方,也就是出了喀布尔城门,他的法令是等于废纸一张的。这就是北洋政府建立起来的方式。没有列强的贷款,阿富汗自然会瓦解成为乌兹别克人、塔吉克人和普什图人的国家,瓦解成为伊斯兰国、塔利班和各个不同政权、各个酋长部落。
▋2002年6月24日,阿富汗临时政府与过渡政府举行政权交接仪式,图为过渡政府总统卡尔扎伊在交接仪式上发表讲话。

早期的中华民国就是这样建立起来的。它跟法兰西共和国和波兰共和国是不一样的。我们可以看出,法兰西共和国和波兰共和国,无论它做得对还是做得错,它建立新体制的力量是来自于自身的。法兰西共和国不是靠卢布打仗的,也不是靠日本浪人来发动革命的。法国的革命家就是法国人自己。他有足够的力量建立新的体系,而且还能够向外输出。所以无论它做得有理没理,法兰西共和国和波兰共和国能够站得起来。

但是中华民国站不起来。为什么呢?因为它所在的社会,十八省的社会、满洲和东三省的社会、蒙古和西藏的社会,它产生不出来自身的建构力量。中华民国只在北京存在,就跟阿富汗共和国只在喀布尔存在是一样的。在其他地方它只是一个象征性权力。它的内部产生不出这种力量来。而国民党和(略)后来想建立它自己新的体制、建立它自己新的资源的时候,它准确地评价了晚清和中华民国这个体系的虚弱和错误和各种各样的弱点,但是它自己的理论也是神话,因为它自己同样没有办法在这个体系内部任何一个地方集结起能够建立新体系的力量。

我们要明白什么叫做革命,革命有一个先决条件就是社会的存在,有有效存在的社会,然后这个社会才有可能发动革命。而东亚社会近代以来的特点恰好是,传统的社会迅速溃烂,而新的社会建立不起来。在这个阶段,任何社会内部的人,他都只能破坏,不能革命,他没有革命的力量。他也许会产生出像白狼(原名白朗,河南宝丰县人,民初流寇头领。白狼集团流窜五省才被剿灭,袁世凯在给段祺瑞的信中说:“白匪久不平,各国报纸谓政府力弱……殊损威信,因而近日中国债票跌至百分之十二三,续借款更难办,关系全局甚重。”)这样的流民或者其他什么团体,但是任何一个内生性团体都没有力量改变这整个社会。
木版年画《白狼过秦川》

东亚社会在清末以来能够产生出的最强有力的组织是什么呢?我们老老实实承认,那就是曾国藩。曾国藩像明朝的戚继光一样,他是什么人呢?他是地方上的地主。地方上的地主,一群地主联合起来,各人出一笔钱,然后练一批保境安民的团练。在官兵都打不赢的时候,他们凭借这个团练首先是保卫家乡,然后就出省作战。这就是儒家传统社会能够产生出来的最有效的组织了。在曾国藩以后产生出来的类似组织没有一个能比湘军更强的,只会比湘军更弱。我们可以说,李鸿章的组织比曾国藩更弱,袁世凯的组织又比李鸿章的更弱,它是一个不断弱化的过程,对应于清朝末年的时候儒家传统社会在不断解体。

旧的社会已经解体,新的社会还没有建立起来,革命的力量不可能来自于社会内部,只能依靠社会外部输入。所以辛亥革命必须要依靠同盟会和日本浪人的力量,北伐战争必须要依靠苏联卢布的力量,(略)的革命则依靠满洲国的工业基础和苏联的冷战干预。他们的核心力量和核心干部都是外来的。外来,就有两个层面:一方面是他们的开支,金钱和武器是外来的;另一方面更重要的是,他们的组织模式也是外来的。如果不是外来的,他们的革命是没法成功的。中国近代的革命,它同样是一个建构的过程。法兰西的革命和战争建构了法兰西民族,波兰的革命和战争也建构了波兰民族。中国的革命和战争,同样也是一个企图建构中华民族或者企图建构中国的过程。之所以没有像法兰西和波兰那样成功,最根本的原因还是因为,法兰西和波兰有自己的社会,而东亚这个地区没有自己的社会。

依靠外来的秩序输入建立起来的秩序本身是脆弱的。它在进攻的时候显得非常强大,那不是因为它自身的强大,而是因为敌人的软弱。为什么区区几十个日本浪人就能够在大明翻江倒海呢?为什么他们不能到香港和马来亚去翻江倒海?那是因为大英帝国在东南亚的统治比大明帝国的统治要坚强得多。为什么一群布尔什维克能够在中国翻江倒海,在波兰却被打得头破血流呢(1920年苏波战争中,Lenin试图对波兰输出革命,但波兰各阶层一致抗俄,最终击败苏俄Hong军)?那是因为波兰民族已经存在,而且有坚强的组织;而蒋介石所设想的中华民族则是仍然是一盘散沙,处在涣散的状态。国民党在推翻大清的革命的时候显得非常坚强,但是它的力量其实只是一群华侨的资本、一群日本浪人和日本的在野党。这些人在日本基本上是微不足道的力量,在大清却显得非常可怕。(略)在革命的时候,它在中国显得非常可怕,让蒋介石对付不了;但在苏联、在斯大林脚下,他们像是一群苦力一样可以随便欺负随便杀。到波兰去,形势就完全不同了。不是说波兰(略)特别弱而中国(略)特别强,而是因为波兰社会已经足够强,而中国社会还没有建立起来。
孙中山与他的日本友人

于是,外来输入的秩序的特点就是,你在进攻时显得异常强大,而在统治时显得异常软弱。这个其实跟满蒙征服帝国的情况是一样的。你要想一想,为什么蒙古人或者满洲人在入关的时候显得如此强大、所向披靡,在统治的时候又显得如此软弱、任何一支流民武装都可以把它打败呢?它在入关的时候,如此强大的正规军被它打得一塌糊涂;它在统治的时候,为什么地方上的几群盗贼就把它给打得受不了呢?原因很简单:满蒙入关时的强大不是反映了它本身的强大,而是反映了它相对的宋明社会的涣散和软弱。在春秋战国时代,草原上的游牧民族对待赵武灵王或者是齐桓公这样的诸侯是非常软弱的,那时候诸夏列国很容易扩张而蛮族很难征服。而到宋明时代,情况就颠倒过来了。部落组织坚强团结,郡县制下的散沙社会混乱懈怠。双方的组织资源颠倒过来了。因此满洲人和蒙古人凭借他们的组织优势,轻而易举地把他们的草原秩序输入到秩序瓦解的散沙社会当中。

但是他们一旦进入散沙社会当中,就面临着不可克服的困难。原有的草原秩序输入,在开国时代还仍然存在,随后就越来越少。开国初期的元朝和清朝仍然是一个草原帝国,那时候它的骑兵仍然非常有战斗力,本土的任何军队,无论是暴民武装、邪教组织还是什么军队都打不过它,它可以轻而易举地维持统治。但到晚期,它就逐步地演化成为跟以前的宋朝和明朝没有区别的官僚帝国了。这时,来自沙漠和草原的新的野蛮民族进攻它,就像当年它进攻宋朝和明朝一样的容易;内部的流民组织和邪教组织发动叛乱,也就像过去宋朝和明朝的宋江、方腊、李自成、张献忠一样的轻而易举。

近代中国的建构其实就是这样的。许多知识分子很悲凉地希望东亚社会本身能够产生出足够的秩序,建立起一个伟大的中华民族或者是其他实体来。但他们都失败了。真正能够站得住脚的,都是从境外输入的秩序的力量。国民党在拥有黑龙会支持的时候显得非常可怕,像现在的伊斯兰国一样可怕,他们拿着炸弹到处炸,虽然炸弹没有几个,但是满清的权贵基本上是吓破了胆了。当时的情况,照唐德刚的话就是,革命党一说有那个炸弹,可以令三岁童子不敢夜啼。而摄政王和他的左右大臣之所以最后愿意乖乖交出权力,归根结底就是因为彭家珍(1888-1912,京津同盟会暗杀部负责人,计划刺杀内阁总理大臣袁世凯、宗社党骨干良弼等人。1912年1月16日,他们刺杀袁世凯未命中;26日,彭家珍用炸弹袭击良弼,自己当场死亡,良弼随后伤重不治)所扔出的那些炸弹。袁世凯和宗社党人都吃过炸弹,那几颗炸弹让宗社党人、让满洲贵族感受到了革命党的可怕,所以他们宁愿是交出政权也要保平安。他们在满洲,当年李自成时代入关的时候不是这个样子的。
彭家珍

国民党在进攻的时候是这样,但等到(略)来的时候,它也变得是异常软弱无力。这个时候,日本浪人和黑龙会已经不再支持它,反而变成它自己的敌人。孙中山时代的国民党可以依靠日本泛亚主义的力量,北伐时期的国民党可以依靠苏联的力量,但是1948年的国民党是既没有日本人的支持又没有苏联的支持又没有美国的支持,于是它面临着新的得到苏联支持的(略)的时候,又变得非常软弱无力了。

(略)在它革命的时候,也像国民党在辛亥年扔炸弹的时候,显得非常强有力。他们像斯大林当年抢银行一样①,在上海资本家的门口放炸弹(参看阿姨《1927,上海滩密谋》),使得所有北洋军阀对他们一点办法都没有。他们依靠苏联的武器支持在东北组织军队,让蒋介石在四川搞出来的那些破军队变得一文不值。蒋介石在四川征出来的那些兵,照他本人下的命令是,他们平时只能吃两顿饭,如果立了功的话可以特许他们吃第三顿饭。而(略)在东北组织的那些军队呢,他们得到的装备比苏联在卫国战争时期还要好,全世界的资源都在为他们服务,不仅有日本在东北建立起来的工业基地,还有苏联的国家计委在第二次世界大战结束以后倾巢动员给它产出的工业产品。

1、斯大林早年经常以抢劫、绑架等手段为(略)筹款(所以列宁说他“是一个极好的格鲁吉亚人”)。其中最有名的一次是1907年6月26日梯弗里斯(今格鲁吉亚首都第比利斯)武装抢劫案。当时一辆银行运钞车在前往国家银行梯弗里斯分行的路上,经过埃里温广场(今自由广场)时,遭遇使用炸弹和枪支的抢劫者袭击。根据官方档案,袭击导致40人死亡,50人受伤。抢劫者共劫走34.1万卢布,这次行动由斯大林亲自领导。
四野坦克大队

你如果去翻沈志华出版的那套苏联秘密档案,你可以看出,满页都是这样的报告:苏联国家计委的官员或者其他官员给本国的各个企业下命令,要节约,把橡胶节约出来支援中国革命;林彪又来跟我们要齿轮来了,赶紧把齿轮节约下来送给他;西方大概已经不用打仗了,美国人运给苏联人打德国人的卡车全部运到东北去;苏联自己产生的工业产出全部运到东北去;共产国际在香港和新加坡设立的秘密机构,把东南亚的橡胶大批运到东北去。因为橡胶是东南亚的主要产品,日本之所以发动大战,主要原因就是因为列强切断了东南亚的石油和橡胶上的供应。但是共产国际有办法把全世界的资源,包括东南亚的橡胶资源,一起运到东北去。而国民党的话,就很难买到那种橡胶。像香港的很多Hong色商人都是在这个时期起家的。他们办的是什么事情呢?他们负责替共产国际和(略)同志采购东南亚的物资,用这些物资来支援中国革命。他们就是这样起家的,整个组织都是在这个时期建立的。在这个时候,(略)也显得非常强大。

但是,经过中苏决裂以后,来自北方的秩序输入切断了。于是,同样一个(略),他的力量就像是失去了草原的元朝和清朝一样,变得非常软弱无力。到了(略)的时候,(略)的飞机已经处在长期不能上天、不能训练的地步了,军官们尽管天天念(略)语录改造思想,但是已经不敢上天了。不敢上天的理由很简单,因为(略)的训练教程都是苏联给他们提供的。自从中苏决裂以后,他们不仅得不到下一批的原子能技术,连飞行员的日常训练都没法维持。于是这时候他只能讲(略)。

我们要明白什么叫做(略)。(略)是一个不得已的概念,实际上就是说是,你失去了苏联给你提供的专业颠覆人员的支持。(略)在自己革命的时候是不讲(略)的,这一点他自己知道得非常清楚。他的人员是苏联训练的,资金和技术都要依靠苏联提供。但他既然跟苏联决裂了,又要提出不同于苏联的革命路线,那他就只有拿他自己有的东西了,就是说靠群众运动。群众运动实际上是他失去苏联组织资源以后,别无选择的一个补救。结果是全部失败。

(五)

一九六零年代以后的反共反苏活动是世界性的。你去看德国现在解密的报告,就可以发现,德国统一社会党(1946年4月由苏占区的德国共产党与德国社会民主党合并组成,苏联在东德的傀儡)跟苏联人开玩笑,把Mao和中国共产党中央去策反他们的材料提交给苏联人。因为中国人出了大笔的钱去给德国统一社会党,希望它带头率领东欧各国TG来拥护Mao当世界革命的领袖,把苏联人排挤到一边去。苏联人看到这些报告,用非常嘲笑的态度来对付他们。但从这你也可以看出,中国共产党当时的进攻是全球性的,遍及东欧各国,遍及拉丁美洲的TG,遍及非洲和东南亚的TG。苏联不断收到报告,说拉丁美洲的TG向他们报告说,TG要给他们多少钱,希望他们跟苏联断绝关系;非洲的TG又得到中国多少廉价武器,希望他们跟着人民战争的道路走。当然拿钱最多的还是东南亚,越南、柬埔寨、马来亚那些地方的TG。

但是这些做法的失败是异常迅速的。可以说,共产国际从二十年代远东共和国成立,一直到五十年代中叶,一直到越南战争,对东亚和东南亚的输入是一个全方位和长时段的现象,费了很大的精力,才最终摧毁了帝国主义和殖民主义在东方的体系。而Mao在失去苏联以后,他搞的世界革命连十年时间都没有维持到,实际上认真算起来只有三到五年时间,就在东欧、拉丁美洲和东南亚全线溃败了。在东欧、拉丁美洲和非洲溃败那是不足为奇的;在它花钱最多、地缘又最近的东南亚,在越南和朝鲜这些地方都禁不住苏联的竞争,那就有问题了。按说支援越南和朝鲜革命,应该是北京最近,它可以很轻而易举地切断苏联的支援。但是苏联还是在这些地方占了上风,那你就不会简单的说是金日成和胡志明个人的权力斗争的问题了。
中国援建阿尔巴尼亚纺织厂的奠基仪式(60年代)

关键还是因为,在六十年代的时候,苏联给这些革命者提供的输出比北京提供的输出要高一级。这是不可避免的,因为武器系统或者其他什么东西,最重要的是层次高而不是花钱多。如果从花钱的角度来看,Mao尽管比苏联要穷得多,但是他送给越南的钱好像不比苏联人少,两者基本上是同一个数量级的。但是,苏联送给它的萨姆导弹,Mao能给它么?Mao失去苏联的支援以后,连自己的飞机都上不了天了,他用什么办法去支援越南的空军和导弹呢。在美国飞机来的时候,是谁能够保护河内呢?只有苏联给它部署的萨姆导弹和苏联飞行员。这些人的人数是很少很少的,顶多就只有几千人,但是没有这几千个苏联顾问的话,胡志明就完蛋了。没有Mao的话,胡志明只是缺了点钱。钱当然是越多越好,但是相比之下还是命最重要。所以越南最终还是倒向苏联了,这是不可避免的。

从长时段历史来讲,你与其像大家这样,分析什么意识形态战争啦,苏联对中国到底好不好呢,双方的共chan主义到底有什么差别呢,不如用更加简单的秩序输入来解释。当初的Mao,他的力量在哪里?他是共产国际的一个支部,能够得到全世界的支援。而跟美国和日本都绝交了的蒋介石,只能依靠抗战以后被打烂了的那小半个中国的资源支持。全世界打一个中国,不仅数量,质量上的差别就不在同一个等级上了,那是很容易打的。六十年代的Mao失去了苏联和全世界的资源,他只能依靠中国大陆的有限资源支持。这个基本盘和1948年的蒋介石是没有很大区别的,所以六十年代的解放军比起朝鲜战争时期的解放军要弱得多。

朝鲜战争时期,苏联生产出来的大批武器是直接送到东北去支援林彪的,苏联的飞行员是直接进入东北去进驻的,东北的铁路网有统一指挥,苏联的物资直接通过满洲里,横跨整个东北运到朝鲜去。那时候的朝鲜战场上的志愿军,当时得到的是东方集团最先进的武器,就像1975年的越南得到的是东方集团最先进的武器一样。朝鲜战争上的中国兵团,它的战斗力,论水准来说,已经接近于第二次世界大战时期的日本兵团。只有在这种情况下,它才够资格跟美国人打一下。

苏联援助给志愿军的米格15战斗机

而六十年代的解放军,基本上是,它最先进的武器甚至不是配给自己,而是配给越南军队的,其实也只是一些改良版本的步枪和坦克而已。它对越南最大的贡献就是它的铁道工程兵,但是这些铁道工程兵输出的技术都是五十年代以前的苏联技术。而时代已经变化,苏美竞争所使用的新型技术,已经只有苏联人能提供了。可以说六十年代的中国如果真要跟苏联或任何人打仗的话,它垮台起来,会跟蒋介石一样迅速的。之所以战争没有爆发,主要是因为美国人干预的结果。但是你可以间接地看出,七十年代以后中国在东南亚的处境之所以那么糟糕,就很清楚地反映了六十年代的中国已经变得多么虚弱了。这个虚弱根本上的原因就是因为,它把自己封闭起来,跟gongchan主义的世界体系切断了联系,因此使自己变得虚弱下来了。八十年代初,中国军队在边界上跟越南军队打仗之所以成绩那么糟,那就是因为越南军队代表了苏联七十年代输出的水平;而中国军队则很不幸,仅仅代表了五十年代中期苏联输出的水平。五十年代末中苏决裂以后,解放军的水平就停留在那个时候了。

没有外来秩序输入的共产党,它像是失去草原以后的满洲人和蒙古人一样,是一只失去了牙齿的老虎,它只能依靠本土的组织资源和财政资源。本土的组织资源和财政资源是什么呢?那就是官吏士大夫阶级。满人和蒙古人在他们有战斗力的时代,他们靠的是草原部落的组织力量,这些力量比起汉地的士大夫要强得多。但他们到了晚期,草原资源已经衰竭的时候,他们也不得不依靠科举产生的官员或者士绅阶级来维持统治了。所以1978年的恢复高考其实是一个非常明确的信号,它意味着,经过六、七十年代的折腾以后,在共产国际资源已经彻底终断,而且将来不可能再恢复的情况下,它必须越来越多地依靠本土的组织资源。依靠本土的组织资源就意味着组织涣散和弱化,这是不可避免的事情。只要主要的干部要通过推荐或者是考试的方式产生,那么它的实际组织力量就不大可能比起宋朝和明朝的官吏、比起国民党后期的官吏强得太多。它再也不可能恢复共产国际初期颠覆集团和侵略集团那种强有力的组织能力和战斗力。如果这样的能力还能够维持的话,那么我可以说,像法lun功或者是全能神教这样的组织是根本成长不起来的。如果是在五十年代的话,它们一露头就会被村党委书记或者民兵队长之类的活活掐死。
1989年冬,北京地坛公园练习罗汉功的民众

八十年代改革开放以后,从西方世界的输入局部地替代了苏联系统的输入。但是西方世界的输入主要是经济上和技术上的,因为我们的接轨也只限于这方面。可以说三十年改革开放得到的成果,主要是中国局部地加入了世界体系,这种输入使它没有像1989年以后的苏联集团那样迅速土崩瓦解。但是,这种输入由于政治、经济相隔离的缘故,并不能够强化组织本身。所以现在的问题就是,起源于共产主义、但是又增加了郡县制官僚帝国成分的这个组织,要统治这个部分地输入了西方资源的半市民社会,变得越来越困难了。

要想解决这个困难,你其实有两种方法:或者,你要听任这个市民社会成长,因为这个市民社会,它的主要的组织资源仍然是从西方输入的,这些组织模式和经济资源的输入会把社会中原有的材料重新组合起来,转换为新的形式,这个形式不可避免地会腐蚀原有的统治形式和政治形式;另一种做法就是,像现在这样,采取重新闭关锁国的政策,封锁互联网,切断和限制信息和资源的输入,保持原有的社会处于一种比较涣散的状态。这样做,残存的统治结构仍然能够保存一定的组织优势,这样他们能够降低统治的困难;但是这样做的结果必定会使勉强建立起来的这个半市民社会,它跟世界主流的差距从此越拉越远。

实际上这正是满蒙帝国在晚期的情况,它跟长城以外的草原帝国的技术落差不断的扩大。长城就意味着隔离。在王朝开始的乱世,可以说处在技术自由流动的情况下,在残酷的杀戮和竞争当中,军事集团能够得到比较先进的中亚技术;长城的隔离作用发挥出来以后,中亚各部落演化仍然不断发展,而关内的军事力量不断地退化,最后总有一天长城会倒塌的。但是,你只要能够把封锁做得足够好,让朝廷的官兵的组织力量和战斗力,虽然不如长城以外的新的部落,但是仍然可以对本土的士大夫的民兵和一盘散沙的顺民保持相对优势,那么你在内部的统治仍然是可以维持的。尽管这个统治,不可避免地,顺着时间拖延,要变得越来越弱。

这就是我们现在所处的真实状态。知识分子制造出来的各种理论和这个真实状态是完全脱节的。他们所制造出的理论都是把中国当成一个已经建立起来而且永远不会变化的政治体,而且把我们所面对的这整个世界看成是一个已经凝固的政治体,它的原则和结构今后都不会发生重大的变化。但是情况显然不是这样。最重要的就是,在世界秩序的中心,新的结构正在出现,原有的、二战以后和冷战以后基于共识政治建立起来的这种稳定的宪法结构,正在面临挑战。欧盟目前面临的危机就很明显是这种挑战的体现。因为我们目前还处在局中,不能够预见这种挑战在欧洲会演化到什么方向。但是根据历史的经验,只要欧洲的游戏规则发生变化,那么新的游戏规则,不可避免地从历史的中心区输入到全世界其他地区,肯定远东不会例外。像那种旧规矩还没有建立、新规矩又进来捣乱的局面很快就要发生了。

同时,你如果把现有的中国已经当成一种法兰西式的民族国家,那你会犯严重错误的。因为它内部的那个失去秩序输入的列宁主义的根基还存在,它自己虽然不足以维持原有的组织力量,但是仍然有足够的力量妨碍一个法兰西式的民族国家的成立。所以你如果根据一个前提,把中国法律当成欧洲大陆法的类似物,以为中国和英美的差距只是拿破仑法典或者欧洲各国大陆法系、罗马法系跟英美法系的差别,那是要犯严重错误的。大陆法系跟英美法系虽然不同,但是跟列宁主义所制造的那种无限战争权力是有重大区别的。而我们必须面对现实:如果列宁主义政党丧失了它对社会实行无限制战争的权力,它本身的统治是无法维持的。

在这种情况下,你即使按照法国和德国的方式,以大陆法为基础建立一个威权主义的国家也是办不到的。这种事情在明治维新以后的日本可以轻而易举地做到,在世界上大多数国家也可以轻而易举地做到,但是在中国这是不可能的。因为每一个国家、每一个民族都是造就它的战争和革命的产物,它的性格和命运是由这些战争和革命本身造成的,而我们只要回顾历史,看看造就现在中国的战争和革命是循着怎样的路线展开的,也就可以大致预测它的命运了。只要它坚持内部的宪法结构不变的话,那它融入世界体系的可能性其实是微不足道的。

如果它的实力不断增长,那么它跟世界体系的冲突必然会加强。如果你像不丹一样软弱和偏远的话,那么即使你的游戏规则完全不同,影响也很小;但是如果双方之间的接触和利益交织已经大到现在这种地步的话,那你会发现,不同的游戏规则每天都在发生冲突。像南海岛屿这些事情,你轻而易举就可以看出,从局部的具体问题背后,体现的是三种体系是怎样冲突的。第一种体系,那不用说,是以西方为中心、经过数百年的长期演化形成的国际法体系。国际法是各种习惯的产物,而习惯是不断积累和演化的,并不是一成不变的一个法典。这一方面,中国人,包括中国的国际法专家其实都没有搞清楚,他们总把国际法当成是制定法一样,是一种不变的东西。其实国际法也是习惯。就是根据这种逻辑,他们才说为什么美国不参加海洋公约什么什么的。其实海洋公约这种东西主要不是各国签署了条约或者是制定了法律,而是几百年以来,各个政治实体在海洋上长期博弈形成的习惯。

中国的问题不是违反了条约的哪一部分,主要是,它自己的行为习惯不符合世界各国长期博弈演化出来的这些行为习惯。它的行为习惯是什么呢?是一种阿米巴原虫式的扩张,美国海军把它称之为色拉米香肠战术。就是说,我先在岛上造一个小的基地,然后一点一点填,把岛填得越来越大。开始的时候这个岛是我和菲律宾人、越南人都来来去去,说不清楚谁占上风的,然后我先把岛填大了,把自己的军事基地做大,然后开始拦截和骚扰其他国家的补给船只。比如说菲律宾在那里的军队,我烧了它的补给船只,让补给船只长期运不进来,然后岛上的军队连续几个星期没吃的,它就渐渐撤走了。像美济礁(位于南沙群岛中东部海域,不久前,☭国在这里修建机场)或者其他这些礁岩,从九十年代以来,冲突就是这个样子,用这种方法一点一点把菲律宾压出争议的海域。

这种做法,按照国际法来说,应该是没有先例的。各国有相互之间的交涉和打仗,但是很少有用这种莫名其妙的方法解决问题的。但是你如果翻阅共产党的历史,你就会发现,这在共产主义本身来说是非常正常的做法。陕甘宁边区(1937年9月6日根据国共两党关于国共合作的协议成立)就是这样建立起来的。国民党划给陕甘宁边区本来只有二十三个县,但它在抗战时期自己把自己变成三十四个县。办法是怎样呢?因为从理论上讲,共产党已经加入了国军,陕甘宁边区是国民党下的一个自治政府,所以大家都是自己人,不是日本人,本国的一个地方政府和陕西省政府之间的边界是不设防的,最开始就是这个样子的,然后你就可以扩张了。

像绥德县这样的地方,本来不是陕甘宁边区的一部分,我们可以拿它作为一个经典例子。办法首先是这样的:尽管官方组织不进去,但是我们可以派民间组织进去,派白手套进去,这些人成立这个协会那个协会,这些协会的核心都是几个共产党员,但是出面的是开明士绅。外头的人看了以后好像觉得只是普通的民间组织,但是骨子里面全是由共产党操纵的。

渐渐地把地下党组织建立起来以后,然后发展自己的民兵。然后这些民兵因为这个那个的原因,比如说跟当地的地主士绅发生冲突,跟征粮征款队发生冲突,冲突的结果是怎么样?然后民兵向周围的八路军求援,王震同志立刻得到消息以后,派三百名骑兵到绥德去替当地的无产阶级撑腰。然后他进了城以后,因为国民党一个县城总共就只有几十个官吏,要有军队的话也只是民兵,如果国军不来驰援的话,他是斗不过三百名骑兵的。那没办法,三百名骑兵过来了,又是友军,蒋委员长又说了,我们要对友军友善一点,怎么办呢?那我们先招待一下,杀猪杀羊,召集当地的地主乡绅,每人出两头猪、三只鸡过来,犒劳犒劳友军。

犒劳完了以后怎么办呢?按照以前的惯例,友军来了以后,我们是应该犒劳一下,犒劳以后你应该走吧?但是王震同志的军队就是驻下来不走。然后赖着不走,你只有向蒋介石告状。蒋委员长批示说,为了抗日战争的大局,这种小事你就算了吧。蒋委员长远在重庆,他倒是可以算了,你让当地的县官,像何绍南同志(1893-1954,保定军校毕业,历任陆军第三师参谋长、国民革命军第二集团军第二十一师师长、第十一军副军长、第三集团军第十六军军长兼第二十四师师长等;抗战时期任陕西保安司令,被毛称为反共摩擦专家。1954年经公审后处决)这样的摩擦专家,你让他怎么办呢①?八路军驻在他的县衙门口,他自己手下才有十几个人,人家有三百个人。那怎么办呢?又赶不走,没有办法。继续征粮征款,征各式各样的资源来养着你。然后这三百人不会闲着的,他迅速地派人到各乡去,把各乡的什么儿童团、锄奸队之类的搞出来。于是,开始的时候进来的是三百人,两年过去了以后,三百名正规军之外已经有了三万名民兵。于是你何绍南坐在县衙门里面,你只会弄这个县衙门,一下乡就可以看到共产党指挥着民兵在那儿红旗招展地念毛主席的口号。

1、萧劲光《陕甘宁边区的反摩擦斗争》:“随着国民党顽固派加紧制造反共摩擦,这些披着‘合法’外衣赖在边区境内不走的国民党官吏,便成了寻衅闹事的祸根。特别是国民党派驻绥德地区的专员何绍南,更是一个臭名昭著、群众切齿痛恨的反共摩擦专家。……一直到王震同志率三五九旅驻防绥德,并担任绥米葭吴清警备司令以后,针锋相对地同他进行坚决斗争,打掉了他的嚣张气焰。不久,他逃出陕北,到了西安。”
陕甘宁儿童团

这时候你怎么样去有效统治呢?那时候你就得作选择了。你可以做一个开明绅士,开明绅士的意思就是说,我已经知趣了,我干脆加入共产党,做共产党的秘密党员行吧,将来我可以加入政协会议。如果我要顽固地忠于国民党,那怎么办呢?首先我征粮征款就征不下去,共产党第一步是礼貌的,给你送点礼物过来,比如说你家乡是云南人,我给你送点宣威火腿过来,再送上一笔盘缠,这个意思很清楚,你在外工作了这么多年很辛苦的,回家养老是不是更好呢~我们八路军是很仁义的,最讲道义的就是我们共产党,我们连路费都替你出了你还不走么~如果你知趣的话,这时候你就乖乖的走了。你一走,那么八路军和各路的民兵就会进入县衙门,那么这个地方就并入解放区了。大部分人,只要性格不是特别坚强的,到这个时候就拿一笔钱走了。如果他要多拿一笔钱的话,估计八路军还是会给他的,统战嘛,统战是不会省钱的。

但是只有极少数人,像何绍南这种人他就不干。所以为什么毛泽东把他叫摩擦专家呢?你要明白共产党眼里的摩擦专家是什么呢?好,我告诉你,共产党眼里的摩擦专家就是像现在越南和菲律宾这种人,反反复复地骚扰你的供给船只。意思就是说,你想让他自己滚蛋算了,但是人家就是不滚蛋,这种人就叫做摩擦专家。像何绍南这种人就是摩擦专家。对摩擦专家用什么办法呢?文的不行就要用武的,先在各乡掀起阶级斗争,你不是要赖在这儿不走么?那你不能不吃饭吧,你要征粮征款。很好,各乡已经有我们建立的乡委会、儿童团在这里占住,你派下去的征粮征款人员一下乡就被当地的民兵抓起来吊打,或者严重的话就枪毙了。你一个钱也收不到,而且你派出去的人也回不来。这样将来过不了多久就没有人肯替你去了,然后你就坐在县衙里面挨饿。

这时候你是不是还不走?还不走很简单,我们以前早在上海就这么做了,先在你的县衙门口扔些炸弹,然后你如果有家属和亲戚朋友在县里面开裁缝铺什么的,突然会有一批贫下中农到你们门口去闹事,冲进你的店铺把你的绸缎布匹什么的分了,把你的家属打一顿,除了你县衙以外,所有地方都给你打了砸了。你待在里面还不走?好,那下一次你骑着马出来沿河散步的时候,突然不知道从哪棵树后一颗子弹打过来,你的马匹突然倒了,那颗子弹打得是如此之准,离你身体只有几寸远,按说是可以把你打死的,但是他偏偏只打你的马,不打你的人。如果这时候你还不走的话,你回头到了县衙门口,你突然发现,你最信任的姨太太突然宣布我已经加入了共青团的妇女组织了,而且她已经替你把行李收拾好了,放在门口等你走。

这时候你还走不走呢?这时候你再不走的话,彭德怀同志英明地指出来,你再不走,我们老百姓抓你起来公审①。在这件事发生以前,公审的事情已经发生好几次了。在你长期赖着不走的时候,你派到乡里面去的那些干部和胆敢给你交税的人已经被当地的贫下中农抓起来公审了。在共产党让你走的时候你这个县衙门还敢派人下来收税,你这个万恶的税吏毫无疑问是剥削者的代表,贫下中农会召集法庭来把你吊起来打死。同时周围的人谁也不敢向你交税,谁向你交税谁就是反动地主,谁不向你交税谁就是开明地主。

1、萧劲光《陕甘宁边区的反摩擦斗争》:“彭德怀在他的《自述》中曾经写道:一九三九年十一月,他从延安回太行山,路经西安时,在国民党西安天水行营主任程潜处见到过何绍南。彭总对程潜说,那些制造摩擦的‘顽固分子,是秘密的汪精卫,比公开的汪精卫还坏’。当着程潜的面,彭总痛斥何绍南:‘你就是这样的汪精卫,在陕北做尽了坏事,破坏八路军的抗日后方。’临行时,他又警告何绍南说:‘再去绥德当专员,老百姓抓了你公审!’但是,两个月后,这个反动透顶的何绍南,竟然又秘密潜回绥德,鬼鬼祟祟,继续煽动保安队袭击我河防部队,先后打死我机枪连连长和哨兵多人。我派队缉拿,他呆不下去,便率领七个保安队哗变,逃窜到西北当土匪去了。”
▋三五九旅在将绥德国民党专员何绍南成功挤走之后建立了“三三制民主革命政权“。图为在绥德师范召开的干部会议合影。

抗日战争时候的政策大概就是这样的:如果你向蒋介石的人交税,或者是向日本人交税,那你就是反动地主,必须把你打死,打死了以后没收你的家产,就可以变成边区政府的重要收入之一;但是,如果你乖乖地给边区政府交税,而且服从边区政府的意思,绝对不给国民党交税的话,那你就是开明地主。尽管你是地主,共产党要保护你收租,但是你的店铺如果不肯交租的话,共产党还是要打你的。目前这个统战阶段的话,开明地主的财产是要受保护的;开明地主的店铺如果以为共产党来了就可以不交租了,共产党也是要教训你厉害的。这样恩威并施一下,那么大多数地主都是宁愿做开明地主的。

等大多数地主都做了开明地主,极少数不开明的地主、顽固派地主,就是坚持给国民党政府继续交租的地主,那么就毫不客气地被吊起来打了。然后两方面这样折腾几年以后,群众运动和公审技术演练成熟以后,你这个何绍南是没法混得下去的。所以摩擦专家最后就跑到重庆上访去了。但他上访的结果显然是很可悲的。蒋介石,就是我们刚才说的那样,为了装逼和统一战线起见,一般是不肯受理这个上访的。华北之所以沦陷,不像有些人说的那样是蒋介石受骗的结果,而是蒋介石维护统战的必要贡献。

抗战刚刚开始的时候,敌后绝大部分人仍然是国民党军,像鹿钟麟(1884-1966,原为冯玉祥部将,1938年5月被蒋介石任命为河北省政府主席、河北游击司令,到河北省沦陷区领导抗日,不断遭到八路军袭击,1940年愤而辞去本兼各职)的河北省政府、韩德勤(1891-1988,抗战期间的江苏省主席、鲁苏战区副总司令。1943年2月,他率部与扫荡的日军周旋月余。3月18日,在与新四军三师副师长张爱萍联系后,获准进入新四军四师根据地暂避日军,却被新四军袭击俘获)的江苏省政府,大部分军队仍然是国民党军队。但是共产党用我刚才描绘的手段一点一点吃你。像吕正操(1904-2009,原为东北军团长,1937年10月率部脱离东北军,1938年5月整编为八路军第三纵队,成立冀中军区,任冀中军区司令员兼八路军第三纵队司令员)那些人比较知趣,他就自动投到共产党一边,然后就变成了开明将领,由开明将领慢慢地自己就加入共产党了。如果你像是鹿钟麟或者张荫梧(1891-1949,原为晋绥军将领,1930年任北平市长,1933年在河北成立保卫团,抗战后成立河北民军,1939年河北民军被八路军全歼,赴重庆告状,未果)这种人,顽固不化,老子就是不肯加入,那么共产党就用我刚才描绘的那种程序,一点一点地把你的部下给铲除了,等你变成孤家寡人的时候,我们把你礼送出境。被礼送出境怎么办?到重庆去上访。这些人就跑到重庆去上访,向蒋委员长写报告去了,要求蒋委员长替他伸冤。蒋委员长为了统战起见,对他们不理不睬,以大局为重,小事情就算了。
▋1939年8月,晋察冀边区举行精神总动员大会:“拥护蒋委员长,坚持抗战到底”

你如果了解共产党的历史,你就会非常清楚,中国目前在南海采取的这种色拉米香肠战术是怎样搞出来的。欧洲人不懂这一套,而传统的中华帝国,比如说大明帝国、大清帝国也是不懂这一套的。这一套流氓色彩很重、实质属于无产阶级的策略,是只有共产党才能发明出来的。大清帝国和大明帝国玩的是另外一套。大清和大明如果跟越南和朝鲜发生了边境冲突,皇上的意思是这样的:恩威并施,两手准备,只要国王愿意效忠,好好给我上一份奏章,赞颂一下皇帝的威仪,这个化外之地嘛,小意思,我全给了你也没关系,我才不来争这点小土地呢,皇帝拥有四海,这点可怜兮兮的地方没人在乎的,我要它干啥。我不是在乎你这个小岛,而是看你越南国王对我大清皇帝忠还是不忠,你只要对我忠,不要说这几个岛屿你占了没问题,我另外再赏给你些岛都没问题。这是大清帝国的做法。像我刚才描绘那种色拉米香肠的做法,你不用说,那是典型共产党的做法。

所以南海博弈就产生出了三种游戏规则。西方殖民地建立起来的继承国家,像菲律宾这些国家,从它们的宗主国那里学了西方那一套,就是走邪路那一套,他们的走邪路那一套,根据他们的游戏规则实施。而共产党同时采取了两套做法:实际上,它是采取了延安吞并国民党领地那一套办法;在表面上,在外交部宣传的时候,它又采取大清皇帝那一套,我们是中华民族伟大复兴,你们这些小国都要乖乖地朝贡。

这样就造成了很大的误解,有很多人都搞不清楚,现在的中国是什么东西?它到底是大清皇帝的复活,想恢复国际朝贡贸易体系,想搞一带一路、把周围的小国都变成像西哈努克那样来朝贡的对象呢;还是一个像三、四十年代共产党那样企图把你们当国民党人对待的渗透颠覆组织呢?答案是,两者都是。因为我们要明白,我们现在的中国不是明治日本,它本来就是双重国家,它是以共产党为里子、而以中国为外壳的一个国家,它当然有一套双重体系。以中国为外壳,那么它的行为就像一个复活的大清,在礼仪上它像一个大清,但是实际上它的内部组织是由共产党维持,所以它就变成一个以共产党为里子、以大清为外表的一个双重体制。你要理解这种双重体制,才能够理解它貌似自相矛盾的行为模式。

像菲律宾这样的国家,它现在就处于摩擦专家何绍南那种处境上。它采取的做法跟何绍南是一样的,它把美帝当成蒋介石,每一次共产党对它色拉米一下,它就跑到华盛顿去告状,中国侵略我们了,中国是个大国,中国以大欺小了。然后美国人就冒出来了,You’re bullying,你在欺负,你在恃强凌弱欺负小国,我们派舰队出来保护一下小兄弟,吓唬你一下,然后你就会收敛一下。然后等美国舰队走了以后,你又来了。就是这个逻辑。别人心里不明白,共产党心里是非常明白的。因为他们有他们的革命教育和革命经验,没有经过这个秘传心法训练的人是不懂的,以为它像神经病一样,其实它完全清楚它在干什么,而且它觉得它完全赢了。

你不要以为美国军舰来了,它就输了。实际上,它先占领一个岛,修几个碉堡,然后美国人来了,它停一下,等美国人走了,它再占几个岛,再修几个碉堡,一寸一寸的,像变形虫爬行一样,地方越占越多。而美国人老是听到菲律宾来告状,告一次来一次,但它也不能老在这儿,过一阵它就走了,结果到最后吃亏的还是何绍南这种人。蒋介石在重庆日理万机,管着全国的事情,区区一个绥德县在他看来算个屁事;美帝管着全世界的事情,今天管伊拉克,明天管乌克兰,菲律宾这点小事人家也不放在心上。你到华盛顿去告十五次状,说不定有两三次美国人来了,好,然后中国人就撤回去。另外十几次呢,美国人说好好好,我下次再给你处理,然后中国就占着不走了。这样一点一点折腾,早晚会把所有岛都占了。这就是共产党推翻国民党的妙计和诀窍。从它的角度来看,它根本就没有输,无论美国人来多少次,它实际上一面在喊,顽固派在打击迫害我们、侵犯我们的主权,实际上它觉得它占了极大的便宜,因为它的岛屿越占越多,填的面积越来越大,机场越修越大。

早晚有一天,不仅陕北的三十四个县全是它的,连华北的五个省都是它的,江苏省政府的韩德勤被亲爱的陈毅同志包围起来礼送出境了。国民党,最后连蒋介石都受不了了,他不仅到华盛顿去告状,而且到莫斯科去告状。斯大林同志都感到震惊,要求毛泽东对此作出解释。毛泽东作出了解释,但是作出了解释以后他还是占着不走,然后河北和山东的国民党省政府就直截了当地被八路军端掉了。最后,等到抗战结束的时候,你突然发现半个中国都已经是共产党的地方了。这时候毛泽东就突然停下来了,他不再宣布效忠于蒋委员长,不再要求蒋委员长替他镇压国民党顽固派,他宣布蒋委员长本身就是顽固派,斯大林同志和罗斯福同志应该跟他联合起来,制裁一下蒋委员长这个顽固派。

如果你按照这种游戏规则去搞的话,那么你可以想象,有朝一日,中国的军事基地会遍布南中国海的所有岛屿,然后中国人会要求俄罗斯人和美国人联合起来镇压东南亚这些捣乱分子,把他们统统压住。等到这些东南亚国家都变成中国的藩属以后,中国的军事基地也许会一直建立到委内瑞拉和古巴去。到那个时候,它就会突然翻脸,不再要求美国人来制裁李登辉或者阿基诺这样的麻烦制造者,而会要求,干脆利落地打倒这个不公正的国际秩序,建立我们更加公正、更加合理的新秩序了。

你如果了解延安时代革命的真正历史和它的秘传心法的话,要理解共产党的行为是不难的。当然我刚才描绘的那个过程现在还只走到前半截,秩序的生长是需要有资源的,很可能只搞到一半,这是很有可能的事情,因为它挑战的资源不能无中生有,延安时代它还可以依靠苏联的资源输入,而它现在挑战的资源基本上是依靠西方的输入,如果它在这个挑战的过程中切断了它跟国际社会的联系,很可能过不上几年,它自己就会退化到六十年代那种情况。就像六十年代它跟苏联绝交以后,自己的资源会不断退化一样,也可能再过十年以后,它就会退化到无论经济上和技术上讲都没有办法继续玩下去的地步,这是很有可能的。但如果这种局面不出现的话,按照秩序本身的逻辑,它是会往这个方向发展的。

我们要明白,秩序有本身的逻辑,有一定的可预期性,只要你明白秩序本身的性质。比如说,你如果明白美国宪法的联邦性质,那你就可以预见到美国人和德克萨斯人或者和其他人打交道的时候会有怎么样的行为模式,你不需要了解事情的本来经过,只要了解美国宪法你就能够大致预见了。英国人和冰岛人如果发生了冲突的话,那你根据欧盟的宪法结构,你就大致上可以预见到,英国人和冰岛人会怎样处理这样的纠纷。如果加泰罗尼亚人和西班牙人闹出了纠纷,那你也可以根据欧盟现在的规矩,大致上预测到他们会干出什么事情来。你根据中国共产党的行为模式和中国的组织建构模式,你确实可以从它秩序形成和输出的意义上大致推出它将来会干什么样的事情。所以当代国际社会和当代中国的基本格局,就可以用这种方式来断定。

可以说在今天的远东,我们看到的就是这三种秩序。第一种秩序无疑是最强大的秩序,冷战结束以后的西方秩序,笼罩着全世界绝大部分地方,有着最强的力量。大部分从殖民地独立的国家,都像菲律宾一样,它们实行的是西方那一套,是这个体系的一部分。极少数国家是背离这个秩序,在这个秩序之外的,其中包括我们现在的中国。中国的秩序是双重的:一部分是明清以来天下国家积累起来的这个秩序;一部分呢,则是从共产国际到中国革命和越南革命这样逐步慢慢形成的一个革命传统。前一个传统是在阳面的,代表着中国面子上的形象;后一个传统是阴面和实质性的,代表了中国的组织模式和实际行为。理解了这样的双重模式,你才能够理解中国将来的行为。

我想,直到今天,国际社会大部分成员和大部分外国人对这种双重模式都是很难理解的,很难理解的原因就是因为他们没有好好钻研过中国革命史。而且由于他们自己处在世界中心,他们不大关心偏僻地方的事情。比如说你如果住在广州城里面,有人告诉你塔什库尔干发生了什么事情,你肯定是不感兴趣。他们自然会对远东这些偏僻小角落发生的事情不大感兴趣。但这只是以前的情况,如果这几种秩序的发展将来破坏了原有的平衡、引起新的冲突的话,他们早晚也会注意的。那么我刚才描绘的这种秩序研究,也可能在不久的未来,像一九七零年代的克里姆林宫学一样,一变而为全世界的显学也未可知。

但是无论如何,秩序的冲突和博弈肯定意味着原有平衡局面的动荡和破坏,在未来可以见到的时间内,就是各种秩序博弈的时代。也许某一种秩序会胜利,也许它们会在博弈过程中产生出跟原来的三种秩序都不同的新秩序。总之,未来仍然处在一个极其开放的状态。谢谢。

(六)

统战包括两种成分:第一是控制,第二是培养。有时要勒紧缰绳,避免失控;有时要放水养鱼,免得鱼都死了你自己也要饿死。

问:在全球化的时代,中国体制内部是否有吸纳全球经济扩张能量的冲动?

阿姨:有什么样的冲动和你实际上做什么是不一样的。就是说,你可能想做某一件事情但是你实际上做的事情并不一定完全符合你想的。两者之间总是有落差的。从实际上讲,你只能摸着石头过河,做你能够做的事情,试探性的前进,然后做一点,如果能够成功就顺着这个方向做下去,如果不能成功你就撤回来。但是你自己的本性对你做什么事情是有影响的,因为你原有的组织结构就注定了有些事情你容易做得成,另外一些事情你不容易做得成。如果你是鱼你就容易在海里面活动,如果你是野兽的话你就不容易在海里面活动,这是你的先在条件所决定的。所以先天的因素和后天的因素不是截然对立,它们本身之间也是有其自然吻合的。

就全球化来说的话,中国政治精英的行为用统战思维很容易解释。改革开放在1978年开始的时候,他首先想到的是什么呢?是恢复到(由于众所周知的原因,此处有所删减,本文其他删减之处也皆以“略”替代,请读者们原谅。完美版已推送给vip读者。订阅冬川豆会员,请加小编ID:dongchuandouclub)时代的情况,他只否定(略),并不否定五十年代。他没有想到要搞市场经济,甚至也没有想到要搞包产到户。(略)之所以复出靠的是什么?治理整顿,就是恢复(略)从苏联引进的那一套,变成了一套恢复了革命纪律的计划经济。但是实际上有很多事情超出他的意料,像包产到户这件事情就是民间自己搞出来的,黑市之类的事情渐渐出来了。同时,从八十年代初(略)的角度来看,他认为,他处在一种守势,各方面都出现意外事故,他自己的资源有限,必须采取打一部分拉一部分的做法,这就是统战了。在你四面八方都有敌人的时候,你当然要统战白崇禧反对蒋介石了,那就要看谁是你的主要敌人,谁不是你的主要敌人。

(略)的选择是,在各方面来说,政治上的挑战对他是最危险的,文化上的挑战是第二危险的,经济上的活动是不太危险的。如果你自己去发了财的话,对他没有什么特别大的危险;如果你直截了当地要开放政治或者引进西方文化,那危险就大了。所以他的做法是,四个坚持是什么意思?就是,政治上绝对要搞垄断,文化上要搞限制,经济上可以放缓一点。为什么呢?因为经济威胁不是直接的,你可以去实验一下。所以(略)不是改革的主设计师,而是改革的主批准师,他采取的是一个选择性批准的做法。

在列宁主义受到严重削弱以后,市民社会基本上解体以后的这些居民,从他的角度来看就是自发的资本主义因素,各方都冒出头来了,他只有力量打击一部分,那么他就坚决打击威胁政治统治的一部分,集中打击威胁他文化统治地位的一部分,对经济上只求自己发财的一部分暂时放在一边不管。就好像我打蒋介石的时候,我没有必要同时跟达赖喇嘛打仗,我还要统战他,这是同样的道理。但是等到他自己资源足够的时候,那就不一定了。在他资源不够的情况下,那么他优先保持政治,其次保文化,然后保经济。这种做法就是,经济方面的自发秩序产生的时候,他采取批准放行的做法,开绿灯,你可以走,走出什么来说不要紧嘛。就像对股市一样,股票市场搞得好就好,搞得不好我们还可以关掉。总之我开绿灯,让你自己去试验。在文化上,他就不允许试验了,要实行严格审批,选择性的引进。在政治上绝对不能搞试验,四项基本原则绝对不能越雷池一步。这就是他采取的政策。

这种政策你要从西方政治逻辑或者大清、大明的逻辑来看,你是看不明白的。但是你从列宁主义的统战逻辑上看,那是一目了然。这就是统战。统战包括两种成分:第一是控制,第二是培养。如果你把统战对象给整死了,这是统战的失败;但是你如果让统战对象过于强大,失控了,这也是统战失败。从(略)的角度看,蒋介石的四一二政变就是统战失败。我们应该统战国民党,用国民党打倒北洋军阀;但是不能让国民党过于强大,强大了以后会反过来打我。所以四一二政变以后他们就开始反思,这就是统战没有掌握好。但另一方面,(略)以后他们也在反思,这个统战搞得过分了,我们把资产阶级和资产阶级知识分子全部搞死了,那原子弹谁来给我们造呢?原子弹不是民国时期的资产阶级知识分子给我们造的吗?没有他们,我们是既没有技术又没有钱。我们还是要统战嘛,我们连统战对象都没有怎么能行。

所以良好的统战是一个平衡的产物。第一,必须要有统战对象。既要有培养,又要有限制。统战对象不能过于强大以至于失控,但是又不能过于衰弱以至于完全没有利用价值。你必须在这二者之间走平衡。如果他变得太过于强大了,那么你就要勒紧缰绳,好好修理他一下,避免他失控;但是同时他如果变得太虚弱了,那你就要放水养鱼,免得鱼都死了你自己也要饿死。这就是统战的基本原则。

可持续统战的基本原则本质上讲是一个天花板限定。你可以想,你养在马圈里的马怎么也跑不过在草原上的马,所以你用这种圈养的方式搞出来的资产阶级或者知识分子,都不如那些没有被圈养的资本家和知识分子。但是让他们养活你是足够了,只要你从他们这儿得到的资源足以使你维持对广大散沙人民的优势,那你对内统治没有问题的。但是你把这些资源用来对外竞争的话,层次上就会有很大的问题。

层次上的问题你要怎么样解决,就看你怎么样评估了。如果你觉得,现有的情况已经接近于失控,我想,像互联网这种情况就是这样,你就会倾向于限制和收缩;如果你觉得对外竞争的压力是占主要地位的,我们现在在国际竞争中处于下风,你就倾向于放开。这两者之间不是矛盾的,而是同一过程的两个组成部分。可以说,就像韬光养晦和大国崛起的关系:韬光养晦是为了大国崛起;但大国崛起如果失败的话,那证明我们实力不足,我们仍然需要韬光养晦积蓄实力。这是一个弹性的过程,也是我刚才描绘的阿米巴变形虫的过程,扩张一下然后收缩一下、再扩张一下收缩一下的过程。当然这个过程中间不能失控,不能失控就需要你对形势有一个清晰而准确的判断。

问:(略)、朝鲜、越南同为社会主义国家,为何发展路径的差别如此之大?

阿姨:列宁主义国家发展状态的差异是不算大的,因为基本模式都是相似的。有的那一点差异,实际上是反映了一个秩序输出的问题。就是说,秩序输出的中心毕竟是在莫斯科。像(略),(略)跟斯大林好的时候,他就比朝鲜和越南要强大;他跟斯大林决裂的时候,他就比朝鲜和越南都不如了。朝鲜在六、七十年代比东北要富裕得多,为什么呢?因为它有苏联支持,而(略)是自绝于苏联了。但是在苏联瓦解以后,谁好谁坏都要主要取决于跟西方国家的关系了。(略)的优势在哪儿呢?是搭了美国的便车、搭了国际体系的便车。而朝鲜不肯搭这个便车,越南搭便车的时间比(略)晚了十几年,所以显得像是(略)比越南要先进一点,越南又比朝鲜先进一点。

但这些实体从本质上讲,它们都是月亮。月亮的光是从太阳借的,它自己不发光的。这些所谓的后发国家,它们的社会本身都是很涣散的,亟需外来的秩序输入。所以外来的秩序输入好坏对它是一个根本性的决定因素。本土的因素虽然也有,但是相对而言属于分量不足的那个比较次要的因素。从这一点来解释,比用本国政策解释要重要得多。直截了当地说,无论在任何时间地点,小国或弱国的命运主要取决于它的对外政策。不仅在东亚,而且在历史上任何地方都是这样的。如果你老是从它国内去找原因,而不考虑当时的决策人在世界体系中的相对地位的话,得出来的结论都是很荒谬的。

直截了当地说,你如果在整个国际体系中处的相对位置不好,你在国内再英明也没有用;如果你的相对位置比较好,即使你犯一些小的错误也是无伤大雅的。像日本明治维新,其实它采取的许多政策都是很荒谬的,之所以没有搞垮,主要还是因为英日同盟,它选择了搭英国的顺风车,跟着英国人走,保障它的安全。太平洋战争时期,日本人搞出来的很多东西其实本身并不是不合理,之所以搞砸了,就是因为它偏要跟英美对着干。简单粗暴地说,答案就是这个样子的。所有因素都有作用,但是有些因素的重要性大到可以把其他的因素压到微不足道的程度。

问:那为何这三个国家的自身选择不一样呢?

阿姨:三个国家都谈不上有什么自身的选择吧。像胡志明这个人,他参加gongchan国际,在香港建立印度支那(略)的经历,那是一目了然的。gongchan国际通过远东局指挥整个中国的革命,把广州变成了反对英日帝国主义的革命根据地。他就是搭这个顺风车,在香港和广州建立印度支那共产党的主要根据地。然后他又借着国民党在抗战时期企图在越南建立国民党支部的机会,用越南国民党当护符,扩大自己的范围。这个做法跟共产党通过统战扩大自己范围的做法是相同的。至于金日成呢,他跟周保中他们都是苏联远东军培养起来的,在满洲国时代,他们是远东军伯力(即哈巴罗夫斯克)附近的基地培养出来的一支伏兵,也就是带路党(周保中,1902-1964,1928年入莫斯科东方劳动者共产主义大学和国际列宁学院学习,1931年被任命为中共满洲省委军委书记,后成为东北抗日联军领导人之一。金正日于1932年在吉林安图县成立游击队,后加入抗联。1940年,抗联军队退入苏联。1942年,被改编为苏联远东方面军第88独立步兵旅,下辖四个营,由一个朝鲜营和三个中国营组成。周保中被苏方委任为特别旅旅长,金日成任第一营营长,直接受周保中的领导)。随着苏联打败日本进入东北,这些人同时进入了东北。然后苏联把他安置在朝鲜的位置上,他就一直呆在这儿了。在这些过程中间,你很难说他自己有什么选择或者不选择。直截了当地说,你这种所谓的选择或不选择的可能性,就像你选择你老板的可能性一样,你可以选择你的老板,也就是说,你可以不干了,自己饿死,然后让别人去占领这个位置,这就是你唯一的选择余地,除此之外我实在看不出他们还有什么选择余地。

问:当年这三个国家是没有什么选择的,但是目前,我觉得这三个国家的选择还是不一样的。

阿姨:朝鲜的问题是,它没有能够统一朝鲜半岛,所以它永远到不了改革开放的状态。改革开放的前提是要有一定的安全程度的,如果你自己的存在没有足够的安全程度,那你是不敢搞改革开放的。而越南能搞改革开放是因为它已经把南越给消灭掉了。同时还有一个国际方面的因素,越南对中国的做法跟中国对苏联的做法是一样的。(略)在八十年代是依靠美国来压制苏联的,越南也是依靠美国压制(略)的。这是一个马基雅维利式的博弈,弱者为了打倒他的敌人,必须和更强的人联合。(略)处在中间地位,美国处在顶峰,而越南处在下级,那么上级和下级联合起来打中间,那是最自然的权术博弈。苏联在的时候,苏联是主要挑战者,美国是主要的统治者,那么挑战者的挑战者向统治者求助,这是自然而然的事情。双方两面一夹,就使苏联处在腹背受敌的状况。越南也可以用类似的博弈策略来对付(略)。但是朝鲜没有这样的博弈策略,道理很简单,因为韩国存在。只要韩国存在的话,朝鲜永远不会争取到(略)在1978年争取到的那种地位,也永远争取不到越南当局现在在TPP中所争取到的那种地位。

问:从世界格局来看,是否存在某种尺度可以衡量人类文明的进步?

阿姨:那你要看是谁说进步这个词了。我们知道进步这个词最开始是由欧洲的世俗知识分子谈论的,尤其是法国的世俗知识分子和启蒙知识分子。当他们谈论进步的时候,他们是有明确所指的,他们的意思是,罗马教会或者宗教势力垄断是不好的,他们削弱这种垄断是好的,他们用更大的国家权力来节制教会的权力,他们认为这是好的,他们把他们认为好的东西称为进步。后来被称为进步的有很多,比如苏联就认为它自己才是最进步的,(略)也认为他自己是最进步的,你如果要入(略)的话,那就说你是追求进步。因为Maxism从思想脉络上来讲是法国启蒙主义的精神后裔,是启蒙主义向极端方向发展的一个产物。因为中国是苏联的一个分支机构,所以苏联从法国知识分子学来的那套话语体系对我们有不自觉的影响。

进步这个东西,很难说有绝对的标准,关键是要看你自己的价值观。我不能代别人说话,只能说我从自己的价值观来看,我认为文明的标准不是他们所说的进步和不进步,而是多元和一元,或者更明确一点,是层次的复杂性和自发秩序的可能性。如果一个文明的体系比较简单,它的网络结构比较少,层次比较简化,那么它产生新事物和发展的可能性就比较小;如果它的网络非常复杂,像大脑神经元一样复杂,结点非常多,而且非常多元化,那么它产生新事物的可能性就比较大。互联网产生在硅谷附近,这当然不是偶然的,我们确实不能想象它会产生在北京的皇宫附近,因为它所产生的整个结构也就反映了它所在社会的结构。所以,秩序的复杂度和简单度是一个比较好的标准。复杂性的结构比较容易产生出更高档次的能力,有比较强的生存机会和发展余地;结构比较简单的文明则是不大好的。

从这个角度来看,那么法国启蒙运动也好,它的继承人也好,起的作用并不是正面的。他们的主要作用就是简化,他们用民族国家,虽然反对教会不是完全错误的,因为教会做了很多错事,而他们节制教会的暴行和各种武断行为有一部分是好的。但是总的来说,他们用世俗政权来压制民间共同体,用比较简单的体制来取代过去比较多元的体制,是有巨大潜在危险性的。即使在欧洲也是这样。在欧洲,我们可以说,之所以没有出大事,是因为社会原先的多元化程度就很高,所以社会多元化虽然因为他们的活动而受到损失,但是损失还不致命。但在东方,像东亚这种长期专制主义、社会多元化的程度很低、社会网络发育程度很低的地方,哪怕是受到一点点破坏就会造成极大的灾难。所谓“无论资本主义还是社会主义,都是越到东方越残忍”,就是这个道理,因为你本来底子就薄。底子厚的人,生一场小病没关系,好像是没什么影响;底子比较薄的人,哪怕是感冒了一下,你就当场死掉了。东亚社会就属于底子薄那种,所以特别禁不住这种打击。

我们要明白,即使是反对教会也不是绝对正确的,因为西方社会之所以是多元化的,有一个重要的因素,就是教权和王权的长期分离,这个跟好坏是没有关系的。你可以说有些教皇做了好事有些教皇做了坏事,有些国王做了好事有些国王做了坏事,这很正常,人就是有的做好事有的做坏事的。但是,只要他们构成相互竞争的权力机构,那么无论教皇和皇帝都没办法垄断政权了。而在东方则出现了政教合一,或者不说是政教合一,但是至少是高度一元化的状态。

从历史经验看来,高度一元化的社会,它会把本来复杂的组织删改到比较简单的状态,严重地压制社会自身发展的空间。否则大清帝国统治下有三、四亿人口,它怎么反而不如荷兰和英国的几百万人口能够产生很多复杂的组织呢?近代社会是从荷兰和英国那区区几百万人口中发展出来的,就像互联网是从加利福尼亚那几十万人中发育出来的。大清的四亿人口对近代化没有作出任何贡献,而(略)的十亿人口对互联网也没有作出任何贡献,这是什么原因?因为起作用的不是人口,而是组织复杂度。加利福尼亚的几十万人口产生了极高的组织复杂度,就像你这个区区一点大的大脑中包括无数的结点一样。但是我如果给你一卡车的猪肉,它虽然比你的大脑重得多,它里面的结点却比你大脑的神经元要少得多。道理都是一样的道理。重要的是结点多少,而不是其他。

(c) The Collection: Art & Archaeology in Lincolnshire (Usher Gallery); Supplied by The Public Catalogue Foundation

问:为何深圳在三十年的改革开放中展现了与内地不一样的图景?

阿姨:深圳的奇迹其实是很容易解释的,因为它部分地模拟了上海租界和香港的政治体制。换句话说,它在一个高度(略)的列宁主义国家当中,虚拟出了一块相当于汉萨同盟(德意志北部城市之间形成的商业、政治联盟。13世纪逐渐形成,14世纪达到兴盛,垄断波罗的海地区贸易,并在西起伦敦,东至诺夫哥罗德的沿海地区建立商站,实力雄厚。15世纪转衰,1669年解体)的租界。为什么上海租界是远东经济繁荣的中心呢,为什么它比日本、朝鲜要繁荣得多,比大清内地要繁荣得多呢?你如果说是大清的政治体制不好,那日本的横滨都赶不上上海租界的发展,这是为什么呢?因为上海租界实际上是一个微型的城市国家,它像中世纪的汉萨同盟一样,它的主要政权掌握在当地有产阶级和商人手里面,他们通过选举自己的议会,成立了自己的正式政府,实行了Marx最经典意义上的资产阶级专政。而领土国家受的牵累太多,它们的自治程度是较低的,地理位置又没有那么好。

深圳,一方面地理位置接近香港和海岸线,另一方面,它获得了一定的自主权。江苏和浙江的资源不可避免地向上海集中。为什么?因为上海在大英帝国军舰和工部局法律的保护之下,实行了普通法的统治,在这里,你的财产权和交易自由得到了最大限度的保障,而你如果在南京的话,张勋或者冯国璋的部队如果抢了你,你是没办法投诉的。在工部局的统治下,你的财产权是有保护的。同时,上海的地理位置比南京和其他地方也要好得多。深圳所享有的就是这两方面的优势。

但是这两方面它都是不如过去上海租界的。原因也很简单,就是因为(略)的统治比起大清的统治来说要武断得多。它如果要干涉上海自治权,那比大清或者国民党要干涉上海租界是要容易得多的,所以它的处境相对而言要更加脆弱而危险。对深圳这样的地方来说,最理想的就是一个汉萨同盟式的城市结构,这个城市结构应该是从上海、宁波一直延伸到北海,遍布整个东南沿海。这些地方如果都能像汉萨同盟一样建立一系列具有自治权的城邦组织,那么它很容易把至少是整个东亚的经济中心集中到这里来。

其实,深圳得到的,就是内地所失去的。从这一点来说的话,它的成功其实是没有多少可喜的。你也可以想象,如果将来对(略)的压力逐步增加,以至于(略)原有的普通法传统和自治传统受到严重侵蚀,那么(略)连同它附属的深圳,未必不会变成五十年代的上海。这个问题主要要看周围的环境演化。在中世纪末期,安特卫普曾经像一九二零年代的上海和现在的(略)、深圳一样,是经济中心,而阿姆斯特丹则是微不足道的农村。但是西班牙人对尼德兰加强管制以后,资本和人才就统统逃到阿姆斯特丹去了。

(略)的成功,是五十年代以后上海失败的产物,它得到的就是上海所失去的。深圳所得到的其实就是内地失去的,至少就是从宁波到北海这一片沿海地区失去的。如果这一片地区也有良好的自治政体的话,那么资本和人力会自然而然地就近聚集到那些地方,而不会来到深圳。如果你的邻居家都着了火,他们自然会带着他们的财产跑到你家里来,使你的家里显得财产很多。深圳的成功主要是这一方面的成功。或者更正确地说,它的成功是巨大的中华帝国体制过于僵化的一个消极的结果。

 


HOW TO: Start a Chinese Company

$
0
0

HOW TO: Start a Chinese Company

in #liveupdates, Chinese Company, Shenzhen by Ian | 2 comments

foreign-invest-cert

While Shenzhen is becoming “Hollywood for Makers”, and not always in a good way, there don’t seem to be a lot of foreign open hardware/maker/start-up/accelerated/innovated/incubated people starting Chinese companies. As far as we know, we are the first foreign owned open hardware centric Chinese company in Shenzhen. With everything going on here, we definitely wont be the last.

There are three reasons foreigners start a Chinese company: to sell to China’s domestic market, to get legal residency, and to work with small suppliers who can’t accept foreign currency. We are only interested in the latter.

Working with a controlled currency

rmb-note

Chinese RMB is a controlled currency. Money only goes in and out of China for certain purposes, in allowed amounts, with the proper license. Most small Chinese suppliers don’t have an import/export license (and dodge taxes) so they can’t convert payments made in a foreign currency.

compression-molding

That’s why it is almost impossible for you, from abroad, to work with the small, flexible, inexpensive Chinese suppliers we have access to. If you really want to make small scale supply chain mash-ups, say 100 traffic-themed adult novelties, then tiny suppliers are crucial and they must be paid in RMB.

Our solution has always been to partner with a Chinese owned local company like Seeed Studio and FlyLin Consulting to handle our ground operation in China. Now we can pay small suppliers directly.

There are also tons of illegitimate Chinese and foreign agents in Shenzhen who do all kinds of exploitative things to circumvent the currency control system and bring money into the country. We now tell everyone: don’t work with someone in China until you see their import-export license!

Fight zombie lies

HKnotCN

Before we continue, lets take a moment to address a pervasive, zombie myth that rings constantly at every start-up meet-up in town: a Hong Kong company is NOT an alternative to a Chinese company. Despite what agents and drunken foreign start-up groupies tell you, you’re not gonna be wiring RMB into China with your new HSBC Hong Kong account.

This is so obviously false and stupid on every level – if Hong Kong had exemption to the currency control wouldn’t every rich Chinese person setup a  company to funnel money in and out? Yet everyone orbiting the start-up scene will proudly and confidently lay it out like they’re skilled insiders. Morons.

WOOF WOOF WFOE

linlin-office

Officially our company is a WFOE, a Wholly Foreign Owned Enterprise. A simpler, cheaper structure called a FIPE is becoming more common with young entrepreneurs, but we understand it to lack liability protection. Foreign Owned doesn’t refer to us, it actually refers to the Hong Kong holding company that owns the WFOE.

fapiao

WFOE is a massive beast of a company. It files a full audit report every month, it must have a minimum size office, and every single penny of expense must have a government tax receipt (fapiao, above) attached.

Its a real company and its does have some cool advantages over an US-based LLC. We draw actual salary, and personal housing is a 100% tax deductible expense for the company. Profits can be remitted to Hong Kong as dividends and taxed as capital gains, if you’re into that kinda thing. While it may take a year to setup and cost as much as a small car, there are advantages if you actually live and work and run a company in China.

Hold me tight – start a holding company

You can own a WFOE personally, but it is seriously difficult to sell shares or take on partners, and there are massive tax issues.

hong-hong-city

Instead, open a Hong Kong company first, then the Hong Kong company starts the WFOE. There are certain tax benefits for remitting profits back to the Hong Kong company, but we haven’t done it and can’t comment yet. This is our structure, and we understand it to be the same structure Seeed is now using while preparing for IPO. Image source.

The Hong Kong company is quick and easy. Setup takes a week and costs around $700-$1000USD. Supposedly you can DIY, but we tried and eventually used an agent. Beware – the Hong Kong company requires an annual audit by a CPA ($500-$1000) and a registered secretary to file the annual report ($700).

HSBC

Opening the Hong Kong company bank account is simple, but you’ll need an appointment and it will take 2-3 weeks to be approved. We use Hang Seng, but would prefer to have gone with HSBC cause, you know, they print the freaking Hong Kong money. It is helpful to take some invoices or contracts to prove you’re a real company. Monthly fees around $60.

hangseng-onlinebank

The account can hold any currency, and you can exchange between almost any currency online, pretty cool. International wires are done online and cost about $35-$40USD.

Prove you understand basic tax principals

Hong Kong has a reputation as a tax haven. Sure, if you’re a legal resident personal taxes are pretty low, but that’s not much use to a foreigner with a small business.

Corporate tax is 16.5%, but your accountant won’t let you leave profit in the company so you’ll never pay corporate tax anyways! Same with Dangerous Prototypes’ US LLC, a pass-through entity isn’t even taxed! You’ll pay personal income tax in your country of residence, however much that is. Americans are also taxed on world wide income even when paying taxes as a legal resident of a foreign country. Get it?

If someone tells you about low tax Hong Kong companies just walk away, they’re a moron.

Choose your sleazebag agent

Agents are incompetent, sleazy, misinformed, and the absolute worst part of starting a Chinese company. There’s really very little opportunity to DIY a WFOE, so you’ll have to deal with them.

We interviewed 6 agents. Initially we hired the Chinese firm that did the Hong Kong company, but they hadn’t really done a WFOE before and the requirements are too numerous and fluid to leave it in the hands of an amateur. We fired them.

Next we hired a foreign guy who always seemed to have the answers we needed. He was super slimy and went on about having face (connections) and being the fastest in town, a total turn off, but he did seem to know the process.

Our agent misguided us multiple times, delaying the formation and costing money. The agent messed up really obvious and stupid stuff. We felt like he had never done a WFOE before either. Turns out, that was close to the truth. He subcontracted the paperwork to another local agent (Aaron Best), who actually presented at the first Hacker Camp…

sz-credit-registration

Eventually we looked up the agent’s company registration. It isn’t even a WFOE. It appears he had two Chinese people start the company so he wouldn’t have to put up the 10 million RMB capital he registered. If you’re talking to an agent in Shenzhen, be sure to look up the company on the official SZ government business listing to confirm who you’re working with. Here’s our registration.

The agent said the company could be done in a month, but in all it took 4-5 months to complete this initial setup phase. Much of the delay was our own complicated situation because we’re an existing, functioning company. A competent agent would have foreseen and guided, instead ours made everything much, much worse. We paid the guy $7000, which includes lots of government fees.

Get your stuff together

Capital

capital-injection

Up until this year you needed 500,000RMB ($81,000USD) of actual cash to start a trading WFOE. There are no hard limits now, but you have to convince the government you can run your company for a year with that amount.

Everyone says minimum 100,000RMB if you want a work visa. Agents terrified us with likely untrue anecdotes about being deemed unfeasible, so we put up 400,000RMB fully paid. Supposedly this is enough to get 4-5 work permits for foreign hackers to work in our Shenzhen office, but who knows if that’s really true.

You need to prove that you have the full amount, but only 20% needs to be transferred up front. The remaining 80% can be paid over the next 2 years. At least that’s what they say, it seems really unfeasible for a small company because each payment takes weeks of processing documents and updating licenses.

bank-reference

A bank reference letter and a certified balance statement prove you have the capital. Hang Seng’s phone bank sent us to the nearest branch to apply in person, somewhat conveniently located in the bank district of a dusty little boarder town called Sheung Shui. The first Hong Kong metro stop outside China.

The banker insisted, INSISTED, there was no such thing as a bank reference letter OR certified balance statement. After 10 minutes of begging, they uncovered the form for the reference letter, but not the balance statement.

More begging and pleading, but they insisted that there was no such thing and threw us out.  The next day the phone banker sent us the form by email to print and take to the branch. Got the same guy, but no apology for making us schlep back to Hong Kong a second time.

Both letters run about $50 each, and are available for pickup after 10 business days.

Director documents

secondpassport

The director of the company needs to supply a passport. The passport will be out of reach for a reasonably long time, many months, so it is absolutely critical that you get a second valid passport if allowed in your country. It is quite easy in the US, all the Shenzhen regulars seem to have them.

The passport will need to be authenticated. The deal here is that China is not part of theApostille Convention that defines how most countries translate and verify documents.

Authentication is a 1900s era flair of ribbons and wax stamps. The US State Department verifies the passport and makes a copy. The Chinese embassy in the US verifies the State Department copy with a ribbon.  Back in China the government verifies the embassy ribbon with a wax stamp. Or something like that. $1000USD for this frilly anachronism.

Hong Kong company documents

hk-greenbox

All the Hong Kong company “green box” stuff needs to be authenticated by a lawyer (7000HKD/$1000USD). If you have a brand new Hong Kong company the documents are already authenticated, but ours was a year old and it all had to be redone.

hk-greenbox-hack

Speaking of green box, we added a magnetic reed switch and RGB LEDs to ours. Nothing says “business” like a company box with a party mode to celebrate the signing (chopping) of a contract. So far bankers and lawyers don’t seem to find it as amusing as we do.

hkvisa

Expert tip: when signing documents in Hong Kong a copy of your entry visa slip is required. If you’re smart and have the second passport you MUST enter Hong Kong on the passport used to register the Hong Kong company. Our agent neglected to tell us about this, so we had to make two trips.

audit-report

If the Hong Kong company is more than a year old China wants to see an audit report completed by a CPA. Hong Kong companies are required to file an audit report with the Hong Kong government every year anyways, but as a little perk the first is due after 18 months. Everybody knows this, all the agents use it as a selling point.

Dangerous Prototypes Limited (HK) fell into the gap – not old enough to need a report in HK, but old enough to need one in China. Instead of pointing this out and helping us deal with it, our idiot agent said our accountant had failed to file the report on time and we would have to pay fines and could even go to jail. He got us whipped up into a frothy lather and scared the hell out of us.

Nope, just needed to get the audit report done early. The audit took two weeks and cost about $500USD from a Chinese accounting firm with an office in Hong Kong. Submit a Google-translated Chinese copy of the report as well.

Officespaced

office-door

A WFOE office must be at least 30 square meters in commercial zoned space, not an apartment. Agents terrified us with myths about inspections, verification, losing visas, and bribing inspectors, so we were needlessly married to having a big office in Huaqiangbei.

HQB-map

We looked at a lot of offices in three buildings. SEG at the south, the Mr. Goodluck Buy building (not actual name) mid-market, and Galaxy Stars building at the North of the market. Offices run about 100RMB per square meter, plus building fees and tax.

seg
The office is going to sit empty for half a year while the company is formed, so we wanted to pay about $1000USD per month (6000RMB). There were lots of too small offices in the 4000RMB range, and there were lots of really big multi-room offices for 10,000RMB+, but not a whole lot for us.

mrgoodluckbuy

The Mr. Goodluck Buy building is unique. Its owned entirely by one company. That’s easier for a WFOE to work with, and there’s no charge for upgrading to a bigger office in the same building later.

qunxin

We ended up in Galaxy Stars Plaza, the building at the very north end of the market with a helicopter landing pad. No, we haven’t been to the helipad. Yes, we’ve tried. Several times.

Galaxy Stars is the Chung King Mansion of Huaqiangbei offices, a Mos Eisley Cantina of little Chinese trading companies. Perfect place for us, and our logistics company is just a floor below.

office

Initially we had rental agents show us space, but they run you all around unable to get inside any of the offices. Its a joke. Asking the security guard on duty to show us around was much more effective. He found us a perfect 52 square meter office for 6000RMB/month including fees and taxes.

building-tax

The contract needs to say that the owner allows the office to be used for a WFOE. Everyone exchanges ID copies, and they hand over a copy of the building tax license. The contract needs a realtor stamp to be official, the guard found someone to provide it.

China’s clean government

National_Emblem_of_the_Peop

One theme throughout the formation process is that agents tell myths, stories, legends, “conventional wisdom”, and seemingly outright lie about stuff. One agent came into our office and said it wasn’t big enough, he was confident the work visa officer would review the floor plan and ask for a bribe. Image source.

Never, during this entire process, was there even a HINT of corruption in the Shenzhen government. Absolutely everything was by the books and squeaky clean. Follow the rules, file paperwork, wait, repeat. There wasn’t even a remote opportunity for something improper to happen.

Part of our motivation for writing this in such long form is to show how clean the experience was. The only corruption and incompetence we experienced was from agents.

The numbers man

An accounting firm is mandatory. The amount of paperwork they file monthly is epic.

China has two levels of sales tax/VAT. A small tax payer pays 3% VAT on everything purchased, and it cannot be refunded when things are exported or sold.

A general tax payer owes 17% VAT on everything they buy, but the tax is refunded when the stuff is exported out of China.

We have been both, currently we’re general tax payers and that was a horrible, horrible mistake. We haven’t done a VAT refund from exporting PCBs yet, it will be interesting to see what happens.

Accounting prices are the same all over town. 400RMB ($70USD) per month for a small tax payer, 1100RMB ($180USD) for a general tax payer. 50RMB ($9USD) per month per Chinese employee, and 150RMB ($29USD) per month per foreigner. Our accounting firm is acceptable, if a little lazy.

The process

complete-docs-pile

Got all that stuff now? It took us 3 months to get everything in order before filing the first document with the government.

Name check (2 weeks)

name-search

Submit a bunch of Chinese names, the government will pick their favorite. There are all sorts of naming rules. Ours shook out to Shenzhen Hanging from the Cliff’s Edge Electronics Technology Limited Company. “Hanging from the Cliff’s Edge” is the actual translation of Xuan Yaun, which is a close as we could get to “Dangerous”.

Foreign Ownership Certificate (4 weeks)

foreign-invest-cert

Here’s where that Foreign Owned part really clicks. The Hong Kong company applies to the government for permission to open a company in China. China gives us this giant certificate redeemable for one Chinese company. Now we’re getting somewhere.

foreign-invest-details

Notice it says for investors from Hong Kong, Macau, and Taiwan? That’s because it belongs to the Hong Kong company, not us.

Business license (10 days)

cn-company-license

All the documents and the company coupon go the local government. 10 days later we get a business license and a copy. These giant papers will have to be folded and carried a ridiculous number of places over the next several months.

company-permission

We also get a half dozen permission letters from the local government. They want one every time we get permits, a bank account, visas, etc, etc.

The problem with stamps

stamps

So, China enjoys stamps. You need them endlessly. The company has three stamps: general stamp, financial stamp, and customs stamp.

KNOW IT: Domestic company stamps are round, WFOE stamps are oval. Are they really a WFOE? Check their stamp!

personal-stamp

We each have name stamps as well. Literally just a stamp with English names.

During the next phase everyone needs the stamps: accountants, permit and licensing agents, visa agents, the bank. Of course you’re gonna need a little stamp time of your own too.

Here’s the rub: you only get one stamp and its illegal to copy them. Part of what takes so damn long with the WFOE is waiting for stamp time. For a while our stamps were couriered between 6 offices almost daily. This can’t be how Tencent deals, can it?

Mix and serve over ice

This is just the initial setup. To actually do anything with the company we still need a bank license and account (2 months), an import-export license (1 month), a work visa (3 months), and a couple other things. We’ll write these up in less-epic posts in the coming weeks.

Was it worth it? No idea yet. The dust is settling though, and we can see a day in the future when we’re running the company instead of starting it.

This entry was posted in #liveupdates, Chinese Company, Shenzhen and tagged ,, .

Comments



The Skeptic’s Guide To React Native

$
0
0

The Skeptic’s Guide To React Native

It’ll be fine. We’ll just go explore for a bit. We’ll be home by sundown.

I’ve been fielding a few questions lately from friends, colleagues, and clients. People are rightfully skeptical with the hype around React Native. Here’s a low-down of what I’ve been hearing.


It does what?!? Run that by me again?

So get this. You take some:

  • Javascript
  • Something that looks like HTML
  • Styles (Javascript in a CSS dress)

Then don’t compile it.

Instead, throw it into a single-threaded Javascript interpreted environment on a mobile device and see what happens.

Wat?

On paper, this is a clown car and should not work.

SPOILER: It does. Extremely well.

Why do you actually WANT to do this?

Here are my top 3 reasons:

  1. Cross platform.
  2. Amazing development experience.
  3. I can still use Obj-C, Swift &&|| Java too.

React Native and React. Same Thing?

No. Spooky amount of overlap though.

React is for browsers. React Native is for iOS & Android.

React slings DOM elements. React Native pushes native platform views.

React as a “concept” is about constructing views. People have even ported these practices to rendering things for a console.

But there’s a convergence going on though. Especially as of RN 0.18. Is React now called React DOM? I don’t know. Lines are getting blurry.

Is it active?

Very much so. 511 contributors as of this writing. Many new features, fixes, and discussions every version. It’s incredibly healthy.

There is a great community newsletter, twitter action with #reactnative, and 3rd-party components sites.

Is this the part where you tell me its fast?

Yes. Don’t go mining bitcoins, but people are doing some crazy things with it. Fire up the FPS monitor and you’ll see it pinned to 60 most of the time.

Javascript is not the villain you think it is. Running in JavaScriptCore, code flies.

Is it multi-threaded?

No. Well, kinda.

There’s 3+ “threads”. You get to use one directly. That’ll be running your Javascript. Everything is pretty much async in Javascript land, so you’ll rarely be blocked.

And the Javascript thread isn’t the main/ui thread either.

This is big news for Android developers, who have to do all kinds of crazy backflips to stay off the main thread. — Darin Wilson

How often is it updated?

New releases are 3–4 weeks apart. Release candidates often ship shortly after a new release is cut.

What’s the development flow like?

It’s astonishing. Type some code. Hit save. App gets auto-reloaded. Instantly.

You can run the app on multiple devices and emulators/simulators simultaneously. Hot-reloading is incoming soon.

Use your own editor. No need to use Xcode (other than launching) or Android Studio.

Now I need to be an expert in iOS AND Android?

Surprisingly, no.

Sure it helps. But for the most part, you’ll be interfacing with React components (and building your own): views, labels, lists, scroll views, etc. They turn into real native components indirectly.

In my opinion, a background in Javascript will actually help more.

Debugging is probably fun.

That’s not a question.

When your app bombs, you’re presented with a great stack trace showing you line numbers and such. With the right editors and environment variables, clicking on a line in the simulator opens the file in your editor.

Then there’s Chrome debugging. Set a break point. Explore the scope chain. Trace variables. Or, like me, only use it for console.log() and still be happy.

There’s a built in profiler but you can also drop down to Instruments or systrace.

Cross platform? For realz? Cuz I’ve been lied to before.

Yes.

Unless you write native code or use platform-specific React Native components.

The overwhelming majority of your codebase will be portable. In fact, creating a brand new React Native app, sets you up to run on both platforms.

Are people writing libraries for React Native?

Are they ever! And many are cross-platform. You can even use some npmlibraries like lodash, moment.js, Ramda, Redux, and more.

What comes in the box?

Maps, lists, navigators, alerts, and lots more.

Are you going to make me write Javascript?

Wait, I said you should *try* lisp!

Yes. But a modern version (ES6/ES2015). Wait until you see destructuring, spreads, fat arrows, and more in action.

I know I know. It’s still no *insert better language here*.

Can I use things like CocoaPods?

Yes. You can bridge to existing code by writing some wrappers. You write these in Swift or Objective-C.

Is there a best way to build apps?

For bigger apps, definitely look into Dan Abramov’s Redux and Yassine Elouafi’s redux-saga (see my previous blog post </selfpromo>).

It’s still all really new, though. Tom Goldenberg (article) and James Ide(article) have written great posts recently about what works for them.

OK, so who is using it in production?

Of course Facebook is using it in places, but the list is growing!

What does it suck at?

I think most people would say view recycling, push notifications, running in background, not all platform components are wrapped, etc.

Android support is fairly new, but its velocity in feature parity is incredible right now. Here’s a good article on that.

Can I really live-patch my AppStore apps?

Yes.

Apple says they’re cool with this. AppHub, CodePush, and Exponent are doing this now and can help you bypass the #iosreviewtime on the AppStore.

How do I submit to the app store?

The same way you do now. You’re actually making APKs and IPAs. These are native apps.

Fastlane can help automate some of this.


Conclusion

For a little more insight, Marc Shilling has a beautiful write up describing his reservations and revelations stepping into this stack.

At Infinite Red, we keep hearing the same concerns about React Native. Do you? Do you have questions too? You can reach me on the land of tweets as @skellock. Press the ❤ below if you like computers or cats.


10 Things We Learned While Building a React Native App

$
0
0

10 Things We Learned While Building a React Native App


There’s a lot to be excited about with React Native. With it, building iOS and Android apps becomes a fun, enjoyable experience. However, there are a few caveats — things that my partner Nicholas Alan Brown and I wish we had known before we embarked on the journey of making a production-ready app.

As our first React Native app, and all while we both had full-time jobs, we decided to make an iOS app for the Bhagavad Gita — the ancient Hindu religious text. I had experience teaching the text at an Indian university, and thought it would be a simple yet practical project. The screenshots below show some scenes from the final product, available on the App Store.

While building the app was a joy, there were definitely some roadblocks along the way. In this post, I’d like to highlight 10 difficulties that we faced, and in many cases, solved. I think this might be helpful to other independent developers who don’t have the time or resources that big development shops do.

  1. You MUST bundle your app before submitting to the App Store

This is somewhat of an embarrassing pitfall, but it does happen to a lot ofReact Native developers, especially if you don’t have previous XCode / Swift experience. Even though your app may run smoothly on the XCode Simulator, you still have to bundle. If you do not and submit the build to the App Store, it will get rejected every time, usually with a notice like this:

You can see that it took 2 rejections before I caught on that I was doing it wrong! Although it’s exciting getting started and you want to get your app on the App Store ASAP, I would suggest not submitting until (a) you can run your app on your device with a bundle, and (b) you can run the app on your device through TestFlight. Here is some more info on bundling your app. Also, the documentation on bundling is a little tricky, so we will cover that more later on.

2. Upgrading React Native versions

This was somewhat of a difficulty for us. Sometimes we would upgrade to the latest release, and everything would break. Then we would struggle to find stable ground again. The fail-proof method of re-installing dependencies was to delete the entire node_modules folder, shut down all processes, then npm install, cmd+shift + k to clean the build, cmd + shift+b to create the build, and then cmd + r to run the app again. Learning this was very helpful when the latest build didn’t work and we needed to step down a version.

3. Scene Transition Animations

In a reddit thread with the React Native team, we asked the team why the scene transitions with the Navigator component are so slow. It is true that if you simply use the Navigator component, you will find really choppy animation while transitioning between scenes. This choppiness becomes much worse in Android, though I haven’t tried this with the latest versions yet. The React Native team responded by saying that they are working on offloading the JS animations to native code, since the JS code piles up and causes frame drops. There is also the InteractionManager module, documented here. We found that Navigator together with theInteractionManager works quite nicely. However, by this time we had already invested heavily in NavigatorIOS, which is faster and has better transitions, since it is native code. The downside to NavigatorIOS is that it is difficult to manage state with it in complex apps. Fortunately, our app was fairly simple without a large number of routes. In the future, we will be looking to useNavigator instead.

4. ANALYTICS!!!

This was the most frustrating of all the issues we had, simply because we spent so much time trying to figure out a solution. When we first started, we knew that analytics would be a huge part of driving our marketing and development strategies post-launch. We tried to go for a Google Analytics solution, but couldn’t find any React Native packages that actually worked (see the SO post here).

Finally, I decided to write my own bridge for Segment Analytics. I was inspired to do this after hearing Chris Smothers (creator of Posyt) describing how he did the same. Basically, the steps are (1) add the Segment pod to a podfile — instructions given here under the heading Bundling Integrations. The React Native docs also describe how to use podfiles here. (2) In the same section, where it says SEGAnalyticsConfiguration, you add the configuration statement to your AppDelegate.m file. (3) You write a helper module that exports theSegment analytic functions to your app — see the gist here. Finally, you can call the AnalyticsHelper module functions in your app when a user logs in, opens a page, etc.

5. Animations

Animations are a nice feature for lots of apps. Whether it’s when a user submits a comment (notice on the iPhone how the message slides up), or a fade-in on entering a screen, or swiping animation, this is definitely important.

While the React Native Animated module is great and pretty well-documented, there are some things that can make the process easier. We started using theAnimated module for everything until I discovered Animatable. If you’ve ever used the CSS library animated.css, this is very similar — it has a ton of easy-to-use animations right out of the box, and is easily configurable. We utilized animations in particular for our onboarding sequence, which produces a carousel on top of the home screen, which expands and loses opacity upon entering the home screen.

6. @notbrent

This guy is simply amazing. Every time Nick and I had a problem — whether it was with scene transitions, onboarding carousel, swiping animation — the answer would undoubtedly come from Brent Vatne. This guy has been a tremendous contributor to React Native and has a ton of great examples to follow. Follow him on Github. Brent, thanks for all the help :).

7. CodePush

Use it. Just do it. Trust me, it is worth it. I got turned on to CodePush from a presentation at our React Native NYC meetup. Jesse Sessler and Bruno Barbieri from Delivery.com spoke about how they integrated React Native in Delivery.com’s existing iOS app — check out their Medium post here. They also shared how using CodePush has been revolutionary for their company. CodePush allows you to push updates to your apps without going through the traditional App Store updating process. This means your users get your updates silently without any prompts, etc. This is great for many reasons. For one, you can keep reviews for your app instead of losing them for each subsequent release. Also, it allows you to push bug fixes really fast. Thedocumentation is very easy to follow, too.

8. Social Sharing

This is something we struggled with. When we released the app on TestFlight, one of the common remarks was that it took a really long time for the social sharing options to appear after hitting the share button. We were using thereact-native-activity-view package, and decided to scrap it. Now we are using the react-native-social-share package. Instead of having options for everything from email, to text, to Twitter, etc., it just has Facebook share. We found this was significantly faster, but still not great. It turns out that social sharing actions are generally slow, even in native Swift apps, but it would be nice to see some improvements in this.

9. App Icon, Launch Screen, etc.

These are things that can be frustrating if you don’t have previous iOS experience. I was lucky that Nick is a full-time product manager for mobile apps, so I let him cover this stuff, but it is still pretty confusing. And once you get the app icon and launch screens working properly, you still have to submit all different kinds of screen shots for the App Store submission. I’m not an expert in this, but I did find this website helpful for getting the different app icon sizes. I also found the tutorials from Ray Wendlich to be helpful, though the process for submitting to the App Store has changed since the post somewhat. All I can say is just bear through it :).

10. react-native bundle command

First of all, the documentation that comes in your AppDelegate.m is not up-to-date (easy PR for someone). The react-native bundle command has changed in the newer releases, and now has many different options. Here are some of them; (1) — platform this is either ios or android. (2) — bundle-output this is the location of your main.jsbundle file. For us it was ios/main.jsbundle. (3) — dev usually you want to set this to false. (4) — entry-file this is the location of your index.ios.js file (if iOS). if it is located within your directory’s root, it would just be index.ios.js. (5) Finally, — assets-dest — this is very confusing, since it would seem that this is where you specify to bundle your assets. However, in most cases, you don’t want to specify this. Instead, there is a file within your node_modules/react-native/packager directory that bundles your assets for you. Why this isn’t documented very well, I’m not sure. Maybe now it is, but when we were trying to bundle, it was very hard to find this information. Anyways, just run the file node_modules/react-native/packager/react-native-xcode.sh and it will bundle your assets for you. Voila!

Conclusion

I hope you enjoyed this post. Despite all these roadblocks, I am confident thatReact Native has a huge future in mobile development. The two of us were able to get an app up to production-readiness and deployed in about 2 months. Please take the time to check out the free or paid version of the app and give us your feedback. Our website for the app is here.

Also Nick and I would love to hear from you. We help organize the React Native NYC meetup and love building apps on the web and for mobile. Happy coding!


Coding Apps with React Native at Exponent

$
0
0

Coding Apps with React Native at Exponent

If you haven’t built an app before it can be intimidating because there is a lot of unfamiliar territory. Before you get a few years of experience specifically with mobile, it can be helpful to have some advice on what to do and why to do it. And for many people reading this who work on software products and have a career ahead of you, mobile expertise is really important when you think about how people are spending their time and what the next billion computers will look like (hint: Android).

At Exponent our primary focus is mobile and we’ve learned a lot about making apps. These are some of the ways we think about and approach app development, specifically with React Native.


Code Style

We use modern JavaScript, specifically parts of ES2015 and ES2016 that are enabled by React Native’s packager by default, with a few extra features like ES2016 decorators.

Generally, we want our code to be easy to understand and easy on the eyes, and we are pragmatic about how we use JavaScript.

  • We use functional programming in the high-level structure of our programs by using React and Redux. Chains of map, filter, and reduce calls aren’t what’s most important.
  • We use “let” or “var” instead of “const” in most places except for actual constants. “let” looks nicer and reassigning to a variable within a function isn’t a source of bugs for us.
  • New JS features give us more options when writing code but don’t necessarily supplant or deserve more use than old ones
  • Priorities: make it work, make it right, make it fast

Modules

We usually use official JS modules with the “import” and “export” keywords instead of CommonJS modules that use the “require” function and “module” object. The two are interoperable but JS modules meet most of our needs and, by default, handle cycles better than CommonJS modules.

React Native’s packager also supports a Facebook-proprietary directive called “@providesModule” that lets you name your module in a way that’s accessible from anywhere within your package. So, we’ll write:

/**
 * @providesModule Api
 */
'use strict';
import encodeUriParameters from 'encodeUriParameters';
const API_ORIGIN = 'https://api.example.com';
export default {
  async callAsync(method, args) {
    let url = `${API_ORIGIN}/${method}?{encodeUriParameters(args)}`;
    let response = await fetch(url);
    return await response.json();
  },
};

Async Functions

Async functions are finally coming to JS and React Native supports them. Several other languages like C# and Hack have supported async functions for awhile so it’s nice to see them in JS, too. They’re better for writing servers than UIs right now, but we still find them useful in apps.

One convention we use that is more important than it may first look is to suffix all async functions with “Async”. This makes it very clear when we need to await the result of the function without extra static typing, tooling, or other overhead.

async function logAsync(data) {
  let response = await fetch(LOG_ENDPOINT, {
    method: 'POST',
    body: data,
  });
  if (!response.ok) {
    let errorText = await response.text();
    throw new Error(`Failed to log data: ${errorText}`);
  }
}

React Components

All of our React components either use JS’s class syntax or are stateless function components. We mostly use classes because our components are stateful, declare prop types, or have convenient helper methods.

Within classes, we use static class properties to declare prop types:

class Box extends React.Component {
  static propTypes = {
    size: PropTypes.number,
  };
}

One of the best features of prop types is that you can gradually increase their precision as your code becomes more stable. At first you can specify just the props that you think someone is likely to forget or misspell. The types don’t need to be precise either; “PropTypes.any” or “PropTypes.object” go a long way. As the component matures, it makes more sense to spend time filling in the prop types more completely. Prop types also act as a lightweight form of documentation.

Documentation

Accuracy of our documentation is important so internally we lean towards reading code, the source of truth. (For public developer-facing APIs we will author more formal documentation.) When a piece of code has far-reaching side effects, comments are helpful for raising awareness of the fuller context.

For processes like setting up our development environment or releasing a new version of our code, we write readme files to explain how the processes work.

File Organization

Our files are generally organized by feature — what they do instead of what they are. A chat app, for example, might have directories named “profile”, “inbox”, and “conversation”. We don’t have directories named “models” and “views” except for general utilities or components that help us write models or views.

App Structure

Many apps have a tab bar and allow navigation within each tab’s scene. They also support sliding scenes up from the bottom.

We use a TabNavigator for the tab bar and nested ExNavigators for both navigation within tabs and covering the whole screen with scenes.

The component and navigator hierarchy common to many apps

Since TabNavigator and ExNavigator (and its underlying Navigator, which does most of the work) are written in JS, they work on both Android and iOS.

Data Flow

We use Redux and its React bindings with decorators. For high responsiveness, we efficiently avoid unnecessary render passes by usingImmutable data structures. The verbosity of Immutable’s data structures is unpleasing so we looked into seamless-immutable but switched back to Immutable for its lazy sequences. We sometimes also use Reselect with a custom Immutable-aware selector creator so that we test for value equality instead of reference equality.

Example File

This is an example file demonstrating how we write a module that exports a React component:

JavaScript Preferred

We greatly prefer components that have a consistent API across platforms. Often this means using components written in purely in JS, but it also includes components that present a unified API on top of their native implementations, like View or ScrollView.

JS components are also faster to iterate on in several ways. This lets us polish their behavior more quickly and build components that are comparable in quality and superior in flexibility compared to their system-native counterparts.

Coherent Design

One of our design principles is to give people a coherent, self-consistent experience. We are able to do this best when we can fit our entire vision for the app’s design in our head. This is much easier when there’s only one design instead of two so we aim for a single great design over iOS’s design or material design; that said, there are great ideas in Apple and Google’s design guidelines and we thoughtfully follow them when it makes sense.

Many of the most important apps take this approach. These are two of them:

Instagram consistently uses the iOS-style tab bar at the bottom. The entire design is remarkably similar across platforms.
Google Maps uses the Android-style drawer UI on both platforms.

People with Android phones understand how to use Instagram and people with iPhones understand how to use Google Maps. We expect the designs of more apps to converge as this trend continues.

Evolution

We are always changing how we do things as we build for more use cases. In the next couple months we expect ExNavigator and TabNavigator to undergo significant API changes and work together. Perhaps the most important aspect of this evolutionary development is that we build for our own, real-world use cases. That’s the main reason I believe many of our components and the points covered in this post will work for other people. Similarly, one of the most important features of React Native is that its purpose is to build Facebook; React Native is a means to an end, not the end itself.

It’s been less than a year since React Native was publicly released and we’re already seeing great interest in the technology. Over the next two to three years as Exponent and React Native mature and stabilize, we see the mobile development landscape being in an even better place than we would have expected otherwise.


Special thanks to Nikhilesh Sigatapu for proofreading a draft of this post.

If you liked this post, recommend it to others by clicking the button below. Follow @exponentjs on Twitter for updates and what people are doing with Exponent.


ESP8266 – Wireless Weather Station with Data Logging to Excel

$
0
0

ESP8266 – Wireless Weather Station with Data Logging to Excel

This project is a collaboration between Yves Arbour and Rui Santos.

In this project we are going to establish a wireless communication between two ESPs and send data from three sensors to an Excel spreadsheet. This tutorial shows a wireless weather station with data logging that you can implement in your home.

Before you continue reading this project, please complete the following tutorials: 

If you like the ESP WiFi module and you want to build more projects you can download my eBook called “Home Automation using ESP8266” hereLet’s get started!

Summary

Here’s a Figure that describes exactly how everything works together:

introduction esp8266 wireless station

Parts List

Here’s the hardware that you need to make the weather station:

DS18B20 – One Wire Digital Temperature Sensor

In this project, we will be using the DS18B20 one wire digital temperature sensor. Now, before we get to the programming part, lets learn how to wire up our temperature sensor.

The DS18B20 can be powered by between 3.0V and 5.5V so you can simply connect its GND pin to GND and the VDD pin to 3.3V from the ESP8266.

Then connect the DQ pin to IO04 on the ESP8266. A 4K7 ohm pullup resistor is required on the DQ pin to pull it up to 3.3V.

DS18B20 pinout

Reading ADC Value

We’re going to use the ADC pin to read an analog value and when referring to the ESP ADC pin you will often hear these different terms interchangeably:

  • ADC (Analog-to-digital Converter)
  • TOUT
  • Pin6
  • A0
  • Analog Pin 0

All these terms refer to the same pin in the ESP8266 that is highlighted in the next section (read this article for more information on the ADC pin).

Currently, TOUT (Pin6) has a 10-bit precision and its input voltage range is 0 to 1.0 V when TOUT is connected to an external circuit.

Accessing the ESP8266 Analog Pin

With the ESP-201 is very easy to access the ADC, you simply connect a jumper wire to the pin highlighted in the Figure below.

esp-201

Flashing Boths ESPs with NodeMCU

We are going to use the NodeMCU firmware, so you have to flash your ESPs with NodeMCU firmare.

Downloading ESPlorer IDE

I recommend using the ESPlorer IDE which is a program created by 4refr0nt to upload scripts to your ESP8266.

Follow these instructions to download and install ESPlorer IDE:

1) Click here to download ESPlorer

2) Unzip that folder

3) Go to the main folder

4) Run ESPlorer.jar

5) Open the ESPlorer

Uploading a Script to Your ESP8266 (3.3V FTDI Programmer)

The schematics to upload scripts to an ESP are very straight forward. You only need to establish a serial communication between your FTDI programmer and your ESP8266 (repeat the schematics below for the Client and Server).

Here’s the connections:

  • VCC – 3.3V
  • GND – GND
  • TX – RX
  • RX – TX
  • GPIO 0 – 3.3V
  • GPIO 15 – GND

Writing Your Client Scripts

There are three scripts that you need to upload to your ESP8266 client:

Start by uploading the following script and name it counterMax.lua. It is just a numerical number 1 that does some counting and helps reset your board if it looses connection with the ESP server.

1

When you upload the counterMax.lua script it is expected to print the following error:

uploading counter max

Upload the script below to read the temperature in ºC or upload this script to read temperature in ºF. Make sure you save the file to your ESP with the name ds18b20.lua.

--------------------------------------------------------------------------------
-- DS18B20 one wire module for NODEMCU
-- LICENCE: http://opensource.org/licenses/MIT
-- Vowstar <vowstar@nodemcu.com>
-- Dramatic simplification: Peter Scargill
--------------------------------------------------------------------------------

-- Set module name as parameter of require
local modname = ...
local M = {}
_G[modname] = M
--------------------------------------------------------------------------------
-- Local used modules
--------------------------------------------------------------------------------
-- Table module
local table = table
-- String module
local string = string
-- One wire module
local ow = ow
-- Timer module
local tmr = tmr
-- Limited to local environment
setfenv(1,M)
--------------------------------------------------------------------------------
-- Implementation  you dont get any shorter than this
--------------------------------------------------------------------------------

function readNumber(pin)
        ow.setup(pin)
        ow.reset(pin)
        ow.write(pin, 0xCC, 1)
        ow.write(pin, 0xBE, 1)
        data = nil
        data = ""
        for i = 1, 2 do
            data = data .. string.char(ow.read(pin))
        end
        t = (data:byte(1) + data:byte(2) * 256) / 16
        if (t>100) then
        t=t-4096
        end
        ow.reset(pin)
        ow.write(pin,0xcc,1)
        ow.write(pin, 0x44,1)
        return t
end

-- Return module table
return M

Finally upload the main script to your ESP and name it init.lua.

-- Yves Arbour wireless weather station project with data logging to Excel sheets with Things Gateway
-- code based on the following
-- Rui Santos - ESP8266 Client
-- DS18B20 one wire module for NODEMCU
-- Vowstar <vowstar@nodemcu.com>
-- Peter Scargill
-- Wimp Weather Station by sparkfun Nathan Seidle

wifi.sta.disconnect()
wifi.setmode(wifi.STATION)
wifi.sta.config("test","12345678")
wifi.sta.connect()
print("Looking for a connection")
temp=0
function readds18b20sensor()
    t=require("ds18b20.lua")
   -- print(t.readNumber(2))  for debuging
    temp = (t.readNumber(2)) --GPIO 04
end

winDirection=0
gpio.mode(0,gpio.INPUT)
function readWindDirection ()
    windDirection = adc.read(0)
        if (windDirection < 26) then windDirection=90 --E
       --if (windDirection < 17) then windDirection=113      -- ESE
       --elseif (windDirection < 21) then windDirection=68   -- ENE
       --elseif (windDirection < 26) then windDirection=90   -- E
       --elseif (windDirection < 36) then windDirection=158  -- SSE
       elseif (windDirection < 43) then windDirection=135 --SE
       --elseif (windDirection < 60) then windDirection=203  -- SSW
       elseif (windDirection < 85) then windDirection=180 --S
       --elseif (windDirection < 98) then windDirection=23   -- NNE
       elseif (windDirection < 120) then windDirection=45 --NE
       --elseif (windDirection < 170) then windDirection=248  -- WSW
       elseif (windDirection < 210) then windDirection=225 -SW
       --elseif (windDirection < 275) then windDirection=338  -- NNW
       elseif (windDirection < 380) then windDirection=0 --N
       --elseif (windDirection < 500) then windDirection=293  -- WNW
       elseif (windDirection < 750) then windDirection=315 --NW
       elseif (windDirection < 1005) then windDirection=270 --W
       else windDirection=-1
       end
end
irqPin = 1  --GPIO5
windSpeed = 0
windClicks = 0
lastWindCheck = 0
function debounce (func)
    local delay = 100000
    return function (...)
        now = tmr.now()
        now = now - lastWindCheck
        if now < delay then return end
        lastWindCheck = tmr.now()
        return func (...)
    end
end

function windSpeedIrq ()
    windClicks = windClicks+1 * 10000000
    print (windClicks)
end
function calcWindSpeed ()
    local deltaTime = tmr.now () - lastWindCheck
    windSpeed = windClicks / deltaTime
    print(deltaTime)
    windSpeed = windSpeed * 1492 /10000 -- Replace " *1492/10000 " with " *24/100 " for Km/h instead of Mp/h
    windClicks = 0
    lastWindCheck = tmr.now()
end
gpio.mode(irqPin,gpio.INT)
gpio.trig(irqPin,"down",debounce(windSpeedIrq))

file.open("counterMax.lua","r")
counter=(file.read())
file.close()
  tmr.alarm(0, 2000, 1, function()
   if(wifi.sta.getip()~=nil) then
          tmr.stop(0)
          print("Client IP Address:",wifi.sta.getip())
          cl=net.createConnection(net.TCP, 0)
          cl:connect(80,"192.168.4.1")
          tmr.alarm(1, 5000, 1, function()
          counter=counter+1

        readds18b20sensor()
        readWindDirection()
        calcWindSpeed()
        print (temp)
        print(windSpeed)
-- Next is the properly formated string that Things Gateway needs to show Date,Time,Wind speed,Wind direction and  Temp.
  cl:send("XLS,write,Example,A"..counter..",%date%\nXLS,write,Example,B"..counter..",%time%\nXLS,write,Example,C"..counter..","..windSpeed.."\nXLS,write,Example,D"..counter..","..windDirection.."\nXLS,write,Example,E"..counter..","..temp)

  cl:on("disconnection",function(reconnect)
    file.open("counterMax.lua","w+")
    file.writeline(counter)
    file.close()
   end)
       end)
   else
         print("Connecting...")
       end
end)
function reconnect()
wifi.setmode(wifi.STATION)
wifi.sta.config("test","12345678")
wifi.sta.connect()
end

Client Circuit

Follow this circuit to build your ESP client and if you are using the ESP-12, you can view the schematics here:

weatherStation-201 Sketch_bb

The right switch connected to IO05 is used to simulate wind speed. The program currently doesn’t give a real-time wind speed, but a last 5 seconds wind speed average.

So it doesn’t mater how fast you press right switch. If you push right switch 5 times in the 5 seconds sampling period… that translates into once per second average giving 1.492 MPH or 2.4 KMH (at this point we’re using NodeMCU integer version, so you’ll get 1492 MPH and 24 KMH. You’ll have to divide in the spreadsheet by 100 and 10 respectively).

Writing Your Server Script

Upload the following script to your ESP and name it init.lua.

-- Rui Santos - ESP8266 Server
-- Modified by Yves Arbour to ennable print string to go directly to an Excel sheet with Things Gateway

print("ESP8266 Server")
wifi.setmode(wifi.STATIONAP);
wifi.ap.config({ssid="test",pwd="12345678"});
print("Server IP Address:",wifi.ap.getip())

sv = net.createServer(net.TCP)
sv:listen(80, function(conn)
    conn:on("receive", function(conn, receivedData)
      --print("Received Data"..receivedData)
        print(receivedData)-- string "Received Data" removed...
        --Things Gateway ignores strings that do not start with proper command...
        --XLS in this case for Excel sheet
    end)
    conn:on("sent", function(conn)
      collectgarbage()
    end)
end)

Final Server Circuit

Follow this circuit to make your ESP server and if you are using the ESP-12, you can view the schematics here.

WirelessWeatherStationServer_201_bbWe’ve created a custom PCB for the ESP-201. Here’s the details:

  • Yellow wire: can either connect GPIO 0 to GND to flash NodeMCU firmware or to VCC to save scripts to ESP
  • GPIO15 is hard wired to GND
  • Reset button and 10K Ohm pull-up resistor to RST pin (in order to reset the board the RST pin has to be pulled down and then has to go back up)

ESP8266 with PCBs

Putting Everything Together

Power both your ESPs and make sure the ESP server still has the serial communication established with your computer, because that’s how you are going to post the data to your Excel spreadsheet.

Downloading and Installing Things Gateway

For this project we are going to use Things Gateway a software by Roberto Valgolio to write data on an Excel spreadsheet and display a self updating real time charts.

Things Gateway is a PC application that connects a microcontroller and makes it able to:

  • Get data from Excel files
  • Write Excel files
  • Write CSV log files
  • Send emails (when certain conditions are met)
  • Show values and charts (charts are Excel independent)

Things Gateway can also connect a GPS and show on the screen:

  • Speed, heading, altitude and other navigation info
  • Real-time tracks in Google Maps

Go to the Things Gateway website, download the program and install it. This project was tested with the Beta4 version.

ThingsGatewaydownload

Launching Your Things Gateway Application

To launch the Things Gateway application is very straight forward. Go to Your PC > Documents > ThingsGateway and open the application.

things gateway app

Then follow these instructions:

  1. Go to the Config tab
  2. Select the Serial COM Port of your ESP8266 Server
  3. Set the Serial port Speed to 9600

 

Related Content: Like ESP8266? Check out Home Automation Using ESP8266

things config

Demonstration

Open the RealTime tab and select From Serial to Excel.

ThingsGateway

An Excel spreadsheet should appear and your data should start appearing there every few seconds!

ThingsGateway excel

Your data is being stored in the example Excel spreadsheet in that folder:

things gateway example

Future Improvements

In this tutorial we established a basic system to send data wirelessly to an Excel spreadsheet using 2 ESP8266 and Things Gateway software.

With this example, you’ll be able to explore more features from Things Gateway like:

  • Real-time self updating graph (not Excel dependent)
  • Data logging in .csv files
  • Auto email sending when custom conditions are met (strong wind above so many kmh, temp to low… warning of heating system failure or freezer not cold enough etc)
  • Data logging in stream.txt that can be replayed at speed 0.1, 0.5, 1, 5, 10, 60 or 3600 times faster
  • GPS track can also be streamed on Google map at actual speed or 0.1, 0.5, 5, 10, 60 or 3600 times faster

Further development could also include:

  • Other sensors like bmp180 barometric pressure sensor
  • Light sensors
  • Humidity sensor
  • Any other digital or analog sensor with the use of multiplexing

Please note that Things Gateway was designed to use with Arduino board, but as long as you send the proper string via serial, it can be used with any board.

I hope you found this guide helpful and huge thanks to Yves Arbour that created this project!

Do you have any questions or feedback? Leave a comment down below.

Thanks for reading. If you like this post probably you might like my next ones, so please support me by subscribing my blog and my Facebook Page.


想降膽固醇,不要吃蛋比較好?破解膽固醇的五個迷思!

$
0
0

想降膽固醇,不要吃蛋比較好?破解膽固醇的五個迷思!

作者:張曉卉、黃惠如 2014-03-31 天下雜誌出版

調整字體尺寸

美國心臟病協會建議,一般人每天食用的膽固醇以300毫克為上限,一顆雞蛋膽固醇含量約260毫克,因此每天吃一顆雞蛋應該沒問題。如果是高血脂病人每星期吃2∼3顆雞蛋無妨…

本文出自天下雜誌出版《別讓身體比你老 - 解讀不生病的關鍵》,更多內容>>

高血脂是心血疾病頭號警訊,血中膽固醇過高,容易堆積在動脈血管壁內層,使血管壁變厚變硬、阻塞,容易引爆中風、心肌梗塞、猝死等危機。

想要控制膽固醇,必須先掌握自己的血脂數據,若是出現紅字,建議可掛心臟內科、新陳代謝科、家醫科或一般內科門診就醫。

其次,先從生活型態改善做起,包括多吃高纖維蔬果、減少高膽固醇食物和高飽和脂肪酸油脂,戒菸、運動、減輕體重等,如果採行這些方法3個月,膽固醇指數仍不理想,則由醫師判斷是否要服用降血脂藥物。有幾個治療新趨勢和降血脂迷思,最好先弄清楚。

1.膽固醇愈低愈好?

→壞膽固醇(LDL)應降得愈低愈好,好膽固醇(HDL)數值則不能低於40mg/dL。

LDL是造成動脈硬化、阻塞的罪魁禍首,HDL則扮演血管清道夫角色。有大型研究發現,高血脂症病人服用史塔汀(statin)類藥物,可以明顯降低壞膽固醇、也就是低密度脂蛋白膽固醇,進而減少發生腦中風、冠心病的風險,降低死亡率,延長病人壽命。

因此美國國家膽固醇教育計劃(NECP)的膽固醇治療指引,不斷下修壞膽固醇的控制指標,譬如,高危險群的LDL起始治療標準從130mg/dL降至100mg/dL,並建議那些最高風險的病人可將控制標準從100mg/dL降到70mg/dL。台灣目前健保給付規定也將有心血管疾病或糖尿病患者,低密度膽固醇起始治療調整為100mg/dL。

2.高血脂病人可否不吃藥,用健康食品降膽固醇就好?

醫界認為,健康食品調控血脂功能至多降10%,應做為日常預防或輔助療法,不能取代藥物治療高血脂。

振興醫院心臟內科主任殷偉賢說,一般民眾若是經濟許可想保養身體、或者是親友贈送吃健康食品調控血脂,他沒有意見;若已是三高的病人想靠健康食品取代降血脂藥物,「一個是食品、另一個是藥物,怎麼比(療效)?」高血脂病人應該和醫師仔細討論是否需要用藥,以降低將來發生心血管疾病的風險,才是正確之道。

而通過衛生福利部認證的健康食品也有證據顯示可以調節血脂功能,無須全盤否認,但若有服用健康食品,應該告知醫護人員,以免影響療效。比方紅麴和史塔汀類都是阻斷肝臟合成膽固醇的酵素,會減少肝臟膽固醇製造量,同時使用恐會交互影響。

台灣衛福部通過有調節血脂功效的健康食品有:紅麴、燕麥、綠茶、低糖高纖豆漿、EPA、DHA、番茄汁、幾丁聚醣、類黃酮、甘蔗原素、含亞麻油酸、次亞麻油酸、二酸甘油酯、單元不飽和脂肪酸的食用油等,若想知道你吃的健康食品廠牌是否通過驗證,可上衛生福利部食品藥物管理署網站查詢。

3.膽固醇降下來就可以停藥?

→不可以。高血脂和高血壓、糖尿病一樣,應持續治療。

長期服用降血脂藥物的病人,應該每隔3個月抽血檢查,如果達到治療目標,可與醫師討論是否減量,但應持續治療,擅自停藥或減量,將使膽固醇回升,增加動脈硬化風險,喪失藥物保護心血管的功能。

殷偉賢表示,研究顯示,採用改變生活型態降血脂的病人,大約可降15%的LDL。他建議,病人如果能用飲食、運動改善高血脂最好,但無論如何都千萬不要不吃藥或者自行停藥,任由高血脂侵蝕血管健康。

1987年後,史塔汀類(statin)降血脂藥物問世,有效降低壞膽固醇、提高好膽固醇、清除血管斑塊,降低高血脂病人併發心血管疾病風險,突破醫界過往認為「動脈硬化一旦形成就無法改變」的說法,達到「血管回春」功效。
眾多實證支持史塔汀療效,甚至逐漸將它拿來當預防用藥。「如果能把史塔汀加到自來水裡就好了,」一位心臟科醫師開玩笑說。

但仍需注意史塔汀有肌肉病變、肝細胞酵素升高等副作用,使用時需小心。

4.想降膽固醇,不要吃蛋比較好?

→只要注意份量、避開其他高膽固醇食物陷阱,照樣可享用雞蛋。

美國心臟病協會建議,一般人每天食用的膽固醇以300毫克為上限,一顆雞蛋膽固醇含量約260毫克,因此每天吃一顆雞蛋應該沒問題。如果是高血脂病人每星期吃2∼3顆雞蛋無妨,如果還是想吃,那麼從第4顆雞蛋開始,選擇只吃蛋白(膽固醇含量0)。

應該擔心的是其他高膽固醇食物,比方內臟(腦、肝、腰子等)、培根、蟹黃、蝦卵等,還有留意躲起來的油脂(比方三明治裡的美奶滋)。還有應少吃油炸、油煎或油酥的食物,炒菜宜用單元不飽和脂肪酸高的花生油、菜籽油、橄欖油等。

另個常犯的錯是,嚴格限制攝取飲食中的膽固醇。

事實上,膽固醇有兩個主要來源,一大部份是由身體自行合成產生,特別是肝臟。另一個來源則是食物,但某種程度可影響肝臟製造膽固醇。例如,原本合成1克,如果經由食物吃了0.5克,肝臟就少合成0.5克。所以,身體會調節,細胞也會感受膽固醇的量,自行控制合成膽固醇的量。就算持續用激烈的手段戒絕膽固醇飲食,也只能把血液裡的膽固醇降到某個程度而已。

5.吃素可以降膽固醇?

→吃對素,確實可降膽固醇;若是吃錯素食,對降膽固醇依舊沒幫助。
蔬菜水果沒有膽固醇又有纖維,尤其是燕麥、蘋果、茄子、秋葵、菇類、木耳、寒天等食物水溶性纖維含量高,可減少腸道吸收膽固醇,降低壞膽固醇和三酸甘油酯,生吃或採涼拌、清燙、蒸煮等低油烹調,多吃多降膽固醇。
怕的是過度加工的素食品,或是用重油重糖烹調出來的素食,膽固醇不但不會降低,反而還會升高。

– See more at: http://www.cw.com.tw/article/article.action?id=5057011#sthash.wiN8YyaH.dpuf


Viewing all 764 articles
Browse latest View live