跳转至

远程拍照上传


概述

摄像头调试代码。发指令控制串口摄像头拍照,并读取图片数据上传。


代码

var SERVER_ADDR = "xianhe.tpddns.cn";
var SERVER_PORT = 8008;

var CAM_ADDR = 1;
var CAM_HEAD = 0x90eb;
var CAM_PACKET_SIZE = 1024; 
var s_photo_file_name = "photo.jpg";
var s_photo_size = 0;
var s_photo_cur_addr = 0;
var s_photo_cur_packet = 0;
var s_photo_packet_total = 0;
var s_send_photo = false;

function packetCameraData(addr, cmd, data)
{
    var len = data.length + 8;
    var a = Bytes.create(len);
    a.seti(CAM_HEAD, 0 , "2b");
    a.seti(addr, 2, "1b");
    a.seti(cmd, 3 "1b");
    a.seti(data.length, 4 , "2l");
    a.copy(data, 6, data.length, 0);
    a.seti(Coder.crc16(a.sub(2, len - 4), "xmodem"), len - 2, "2l");

    return a;
}

function  cameraPhotograph()
{
    var a = Bytes.create(4);
    a.seti(0x0002, 0, "2b");    
    a.seti(17, 2, "1b");    //分辨率  1(160*120) 3(320*240) 5(640*480) 6(1280*960) 7(800*600) 8(1024*768) 9(1280*800) 15(1280*720) 17(1280*1024)
    a.seti(1, 3, "1b"); //压缩比

    print("photograph:",packetCameraData(CAM_ADDR, 0x40, a).hex());
    UART.send(2, packetCameraData(CAM_ADDR, 0x40, a));
}

function cameraGetPhotoPacket(addr, length)
{
    var a = Bytes.create(6);
    a.seti(addr, 0, "4l");
    a.seti(length, 4, "2l");

    UART.send(2, packetCameraData(CAM_ADDR, 0x48, a));
}

var dbuf = Bytes.create(CAM_PACKET_SIZE + 8);
var dlen = 0;
function processData(port, data)
{
    if(port == 2)
    {
        dbuf.copy(data, dlen);
        dlen += data.length;

        if(dbuf.geti(0, "2b") ==  CAM_HEAD)
        {
            if(dlen >=6)
            {
                var len = dbuf.geti(4, "2l");
                if(dlen >= len + 8)
                {               
                    if(Coder.crc16(dbuf.sub(2, dlen-4), "xmodem") == dbuf.geti(dlen-2, "2l"))
                    {
                        var cmd = dbuf.geti(3, "1b");                       
                        if(cmd == 0x40)
                        {
                            var time = Box.getTime();
                            s_photo_file_name = time.format("%Y-%0M-%D-%0h-%0m-%0s") + ".jpg";
                            s_photo_size = data.geti(7, "4l");
                            s_photo_cur_addr = 0;
                            s_photo_cur_packet = 0;
                            s_photo_packet_total = Math.floor((s_photo_size-1) / CAM_PACKET_SIZE + 1);
                            var size = (s_photo_size > CAM_PACKET_SIZE) ? CAM_PACKET_SIZE : s_photo_size;
                            print("s_photo_size:", s_photo_size);
                            print("s_photo_packet_total:", s_photo_packet_total);
                            cameraGetPhotoPacket(s_photo_cur_addr, size);
                        }
                        else if(cmd == 0x49)
                        {
                            var photoPacket = dbuf.sub(6, len);
                            Net.send(1, photoPacket, false);    //第三个参数,设置为false,关闭送达确认,加快上传速度
                            Timer.start(4, 200);            //等待200毫秒后再发送下个数据包,太快会堵塞发送队列
                        }
                    }
                    dlen = 0;
                }
            }
        }
        else
        {
            dlen = 0;
        }

    }
}


function handleNetEvent(m)
{
        switch(m.event)
        {
            case Net.READY:
                print("Net.READY");
                Net.connect(1, SERVER_ADDR, SERVER_PORT, "tcp");
                Timer.start(2, 300000);
                break;
            case Net.CONN_OK:
                print("Net.CONN_OK");
                cameraPhotograph();
                var time = Box.getTime();
                print(time.format("%Y-%0M-%D %0h:%0m:%0s"));
                break;
            case Net.CONN_FAIL:
                print("connect failed");
                break;
            case Net.CONN_CLOSE:
                print("connect closed");
                break;
            case Net.RECV:
            print("rec_hex:", m.data.hex());

                break;
            case Net.SEND_OK:
                print("OK:");
                break;
            case Net.SEND_FAIL:
                print("send FAIL:");
                break;
            default:
                print('default')
        }
}

function handleTimerOut(id)
{
    switch(id)
    {
        case 1:
            break;
        case 2:
            Net.close(1);
            break;
        case 3:
            break;
        case 4:
            s_photo_cur_packet++;
            s_photo_cur_addr += CAM_PACKET_SIZE;

            print("s_photo_cur_packet:", s_photo_cur_packet);           
            if(s_photo_cur_packet < s_photo_packet_total - 1)
            {
                cameraGetPhotoPacket(s_photo_cur_addr, CAM_PACKET_SIZE);
            }
            else if(s_photo_cur_packet == s_photo_packet_total - 1)
            {
                cameraGetPhotoPacket(s_photo_cur_addr, s_photo_size % CAM_PACKET_SIZE);
                        var time = Box.getTime();
                        print(time.format("%Y-%0M-%D %0h:%0m:%0s"));
            }
            break;
    }
}

UART.open(2, 115200);
Net.init();
GPIO.set(GPIO.POWER, 1);
GPIO.set(GPIO.OUT1, 1);
GPIO.listen(GPIO.IN1);
while(true)
{
    var m = Event.get();
    switch(m.msg)
    {
        case Event.UART_RECV:
            processData(m.port, m.data);
            break;
        case Event.TIMER_OUT:
            handleTimerOut(m.id);
            break;
        case Event.NET_EVENT:
            handleNetEvent(m);
            break;
    }
}

下载代码(右键另存为):takephoto.js