版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/scylhy/article/details/87598803
Go调用C
过年在家无聊,玩起了大学买的小车,想通过网页操作小车的前进后退转弯,
但是小车的驱动是C写的,而web服务想用Go写,故需要Go调用C.
- Go调用C
#include <stdio.h>
int helloFromC() {
printf("Hi from C\n");
return 0;
}
package main
/*
extern int helloFromC(); //->必须的,import C会解析这个声明
*/
import "C"
func main() {
//call c function
C.helloFromC()
}
#运行结果:
localhost:tmp liu$ ls
hello.c main.go
localhost:tmp liu$ go run .
Hi from C
localhost:tmp liu$
- 小车控制代码
#include <stdio.h>
/*将控制程序改成了输出,方便测试*/
void run(void) // 前进
{
printf("run\n");
}
void brake() //刹车,停车
{
printf("brake\n");
}
void left() //左转()
{
printf("left\n");
}
void right() //右转()
{
printf("right\n");
}
void back() //后退
{
printf("back\n");
}
package main
import (
"log"
"net/http"
"html/template"
)
/*
extern void run();
extern void left();
extern void right();
extern void brake();
extern void back();
*/
import "C"
type Car struct {
IP string
}
func (c *Car) Run() {
C.run()
}
func (c*Car)Left() {
C.left()
}
func (c*Car)Right() {
C.right()
}
func (c*Car)Brake() {
C.brake()
}
func (c*Car)Back() {
C.back()
}
func main() {
v1()
}
func v1() {
//匿名函数注册路由
http.HandleFunc("/", Deal)
log.Println("starting service!")
//log.Fatal输出后,会退出程序,执行os.Exit(1)
log.Fatal(http.ListenAndServe(":80", nil))
}
func Deal(w http.ResponseWriter, r *http.Request) {
//w.Write([]byte("running"))
var car Car
car.IP = "192.168.12.1"
tmpl, err := template.ParseFiles("page.html")
if err != nil {
// Log the detailed error
log.Println(err.Error())
// Return a generic "Internal Server Error" message
http.Error(w, http.StatusText(500), 500)
return
}
if err := tmpl.Execute(w, car); err != nil {
log.Println(err.Error())
http.Error(w, http.StatusText(500), 500)
}
//gen cert
err = r.ParseForm()
if err != nil {
log.Println(err)
}
tForm := make(map[string]string)
if r.Form["action"] == nil || len(r.Form["action"]) == 0 {
}
//return
for a, b := range r.Form {
if len(b) == 0 {
//fmt.Println("a:",a,"b:","null")
tForm[a] = ""
} else {
tForm[a] = b[0]
}
}
switch tForm["action"] {
case "forward":
car.Run()
case "back":
car.Back()
case "left":
car.Left()
case "right":
car.Right()
case "brake":
car.Brake()
}
}
<html lang="en">
<head>
<link rel="stylesheet" href="/static/stylesheets/main.css">
<meta charset="UTF-8">
<title>CAR OP</title>
<style>
*{
margin: 0px;
padding: 0px;
}
.op{
width: 100%;
height: 100%;
background: white;
position: absolute;
top: 10%;
border-top: gray dotted;
border-bottom: gray dotted;
border-width: 1px;
text-align: center;
}
.button{
-webkit-appearance:button;
height: 40px;
width: 200px;
}
.bar{
text-align: center;
}
</style>
</head>
<body>
<div class="bar">
<br>
操作台
</div>
<div class="op">
<form method="get" name="op">
<p class="a">
<br>
{{.IP}}
<br>
<br>
<input class="button" type="submit" name="action" value="forward">
<input class="button" type="submit" name="action" value="back">
<br>
<br>
<br>
<input class="button" type="submit" name="action" value="left">
<input class="button" type="submit" name="action" value="right">
<br>
<br>
<br>
<input class="button" type="submit" name="action" value="brake">
</p>
</form>
</div>
<body>
</body>
#浏览器127.0.0.1,打开控制页面,依次点击产生如下输出
localhost:walk liu$ ls
page.html walk.c walk.c.bk walk.go
localhost:walk liu$ go run .
2019/02/18 09:16:41 starting service!
run
back
left
right
brake
^Csignal: interrupt
localhost:walk liu$
由上述测试结果显示,代码运行正常,可将小车控制程序换成c驱动.
- 小车控制代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <time.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <wiringPi.h>
#define Trig 28
#define Echo 29
#define LEFT 27
#define RIGHT 26
#define BUFSIZE 512
#define MOTOR_GO_FORWARD digitalWrite(1,HIGH);digitalWrite(4,LOW);digitalWrite(5,HIGH);digitalWrite(6,LOW)
#define MOTOR_GO_BACK digitalWrite(4,HIGH);digitalWrite(1,LOW);digitalWrite(6,HIGH);digitalWrite(5,LOW)
#define MOTOR_GO_RIGHT digitalWrite(1,HIGH);digitalWrite(4,LOW);digitalWrite(6,HIGH);digitalWrite(5,LOW)
#define MOTOR_GO_LEFT digitalWrite(4,HIGH);digitalWrite(1,LOW);digitalWrite(5,HIGH);digitalWrite(6,LOW)
#define MOTOR_GO_STOP digitalWrite(1, LOW);digitalWrite(4,LOW);digitalWrite(5, LOW);digitalWrite(6,LOW)
void run() // 前进
{
softPwmWrite(4,0); //左轮前进
softPwmWrite(1,250);
softPwmWrite(6,0); //右轮前进
softPwmWrite(5,250);
}
void brake() //刹车,停车
{
softPwmWrite(1,0); //左轮
softPwmWrite(4,0);
softPwmWrite(5,0); //stop
softPwmWrite(6,0);
}
void left() //左转()
{
softPwmWrite(4,250); //左轮
softPwmWrite(1,0);
softPwmWrite(6,0); //右轮前进
softPwmWrite(5,250);
}
void right() //右转()
{
softPwmWrite(4,0); //左轮前进
softPwmWrite(1,250);
softPwmWrite(6,250); //右轮
softPwmWrite(5,0);
}
void back() //后退
{
softPwmWrite(1,250); //左轮back
softPwmWrite(4,0);
softPwmWrite(5,250); //右轮back
softPwmWrite(6,0);
}
-
Todo
下个假期把小车的超声波、红外、摄像头功能加上