golang, rfid i c - hardgroup langs #1
TRANSCRIPT
GOLang& RFID
Co to RFID?
“RFID (ang. Radio-frequency identification) – technika, która
wykorzystuje fale radiowe do przesyłania danych oraz
zasilania elektronicznego układu (etykieta RFID) stanowiącego
etykietę obiektu przez czytnik, w celu identyfikacji obiektu.”
- Wikipedia
Zarys historyczny
GOLang
CGO
Import C// #include <stdio.h>// #include <errno.h>import "C"
// #cgo CFLAGS: -DPNG_DEBUG=1// #cgo amd64 386 CFLAGS: -DX86=1// #cgo LDFLAGS: -lpng// #include <png.h>import "C"
// #cgo pkg-config: png cairo// #include <png.h>import "C"
Referencje do Cpackage main// typedef int (*intFunc) ();// int// bridge_int_func(intFunc f)// {// return f();// }// int fortytwo()// {// return 42;// }
import "C"import "fmt"
func main() {f := C.intFunc(C.fortytwo)fmt.Println(int(C.bridge_int_func(f))) // Output: 42
}
Typyfunc C.CString(string) *C.char
func C.CBytes([]byte) unsafe.Pointer
func C.GoString(*C.char) string
func C.GoStringN(*C.char, C.int) string
func C.GoBytes(unsafe.Pointer, C.int) []byte
GO w C//export MyFunctionfunc MyFunction(arg1, arg2 int, arg3 string) int64 {...}
//export MyFunction2func MyFunction2(arg1, arg2 int, arg3 string) (int64, *C.char) {...}
extern int64 MyFunction(int arg1, int arg2, GoString arg3);extern struct MyFunction2_return MyFunction2(int arg1, int arg2, GoString arg3);
Budujemy● Na rpi
● Na pc
> GOARM=6 GOARCH=arm GOOS=linux go build examples/raspi_blink.go
> go build -ldflags "-w" .\main.go
RFID - Aplikacja
Mainfunc main() {
reader, _ := rc522.NewRfidReader()readerChan, _ := rfid.NewReaderChan(reader)rfidChan := readerChan.GetChan()doSomethingCount := 0for {
select {case id := <-rfidChan:
fmt.Println(id)default:
doSomethingCount++fmt.Println(" ... ", doSomethingCount)time.Sleep(1000 * time.Millisecond)
}}
}
Interfejspackage rfid
type RfidReader interface {ReadId() (string, error)
}
Kanał do odczytu danych type ReaderChan struct {
reader RfidReaderch chan string
}
func NewReaderChan(reader RfidReader) (*ReaderChan, error) {reducReader, err := NewReducer(reader)if err != nil {
return nil, err}c := &ReaderChan{
reader: reducReader,ch: make(chan string, 1),
}go c.loop()return c, nil
}
Odczyt z pętlifunc (c *ReaderChan) loop() {
for {id, err := c.reader.ReadId()if err != nil {
continue}c.ch <- id
}}
func (c *ReaderChan) ReadId() (string, error) {return <-c.ch, nil
}
func (c *ReaderChan) GetChan() chan string {return c.ch
}
Reducerfunc (r *Reducer) ReadId() (string, error) {
id, err := r.reader.ReadId()if err != nil {
r.oldvalue = ""return id, err
}if id == r.oldvalue {
return id, fmt.Errorf("RFID: duplicate id echo")}r.oldvalue = idreturn id, err
}
RFID - Adapter C
Nagłówekpackage rc522
// #cgo CFLAGS: -I${SRCDIR}/libs/// #cgo LDFLAGS: -L${SRCDIR}/libs/ -lbcm2835// #include <rc522_public.c>import "C"
import ("fmt"
rfid "github.com/firmom/go-rfid-rc522/rfid")
var (instance rfid.RfidReader = nil
)
RfidReader type RfidReader struct{}
func NewRfidReader() (rfid.RfidReader, error) {if instance == nil {
errCode, err := C.InitRC522RfidReader()if err != nil {
return nil, err}if errCode != 0 {
return nil, fmt.Errorf("Init rc522 fail with code: %s", errCode)}instance = rfid.RfidReader(RfidReader{})
}return instance, nil
}
Odczyt z czytnikafunc (r RfidReader) ReadId() (string, error) {
response, err := C.ReadIdByRC522()if err != nil {
return "", err}if response.errorCode != C.NO_ERROR {
return "", fmt.Errorf("Read rc522 fail with code: %s", response.errorCode)}return C.GoString(&response.id[0]), nil
}
RFID - Czysty C
Odczyt z czytnikauint8_t InitRC522RfidReader(void) { uint16_t sp; sp = (uint16_t) (250000L / DEFAULT_SPI_SPEED); if (!bcm2835_init()) { return 1; } bcm2835_spi_begin(); bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST); // The default bcm2835_spi_setDataMode(BCM2835_SPI_MODE0); // The default bcm2835_spi_setClockDivider(sp); // The default bcm2835_spi_chipSelect(BCM2835_SPI_CS0); // The default bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW); // the default InitRc522(); return 0;}
Inicjalizacja rc522void InitRc522(void) { PcdReset(); PcdAntennaOn();}
Odczytstruct CardIdResult ReadIdByRC522() { //vars... statusRfidReader = find_tag(&CType); if (statusRfidReader == TAG_NOTAG) { //... } else if (statusRfidReader != TAG_OK && statusRfidReader != TAG_COLLISION) { //... } if (select_tag_sn(serialNumber, &serialNumberLength) != TAG_OK) { //... } p = result.id; for (loopCounter = 0; loopCounter < serialNumberLength; loopCounter++) { sprintf(p, "%02x", serialNumber[loopCounter]); p += 2; } *(p++) = 0; result.status = TAG_STATUS; result.errorCode = NO_ERROR; return result;}
Czas na demo
Pytania?
go-rfid-rc522https://github.com/firmom/go-rfid-rc522
Dziękuję za uwagę