kopia lustrzana https://github.com/DL7AD/pecanpico10
Updates:
- image command and python script rolled in from webcam_dev branch - further WIP on SSDV buffer full handling (more to do)Development
rodzic
50091cbe78
commit
eb0aad1f70
|
@ -30,9 +30,9 @@ with serial.Serial(port='/dev/ttyACM1') as ser:
|
|||
i=0
|
||||
while True:
|
||||
line = ser.readline()
|
||||
m = re.search("\[(.*)\]\[(.*)\] DATA \> image\/jpeg\,(.*)", line)
|
||||
m = re.search("DATA \> image\/jpeg\,(.*)", line)
|
||||
try:
|
||||
size = m.group(3)
|
||||
size = m.group(1)
|
||||
except:
|
||||
print line.strip()
|
||||
continue
|
||||
|
|
|
@ -50,7 +50,7 @@ const conf_t conf_flash_default = {
|
|||
.cca = 0x4F
|
||||
},
|
||||
// App identity
|
||||
.call = "VK2GJ-11",
|
||||
.call = "VK2GJ-2",
|
||||
.path = "WIDE2-1",
|
||||
.symbol = SYM_ANTENNA,
|
||||
.aprs_msg = false, // Enable APRS message reception on this app
|
||||
|
@ -86,9 +86,9 @@ const conf_t conf_flash_default = {
|
|||
.img_sec = {
|
||||
.svc_conf = {
|
||||
.active = true,
|
||||
.cycle = TIME_S2I(60 * 15),
|
||||
.cycle = TIME_S2I(60 * 2),
|
||||
.init_delay = TIME_S2I(10),
|
||||
.send_spacing = TIME_S2I(2)
|
||||
.send_spacing = TIME_S2I(5)
|
||||
},
|
||||
.radio_conf = {
|
||||
.pwr = 0x7F,
|
||||
|
@ -97,7 +97,7 @@ const conf_t conf_flash_default = {
|
|||
.cca = 0x5F
|
||||
},
|
||||
// App identity
|
||||
.call = "VK2GJ-11",
|
||||
.call = "VK2GJ-2",
|
||||
.path = "",
|
||||
|
||||
// Image settings
|
||||
|
@ -138,7 +138,7 @@ const conf_t conf_flash_default = {
|
|||
// If there is no cycle time or interval then run continuously.
|
||||
// If there is a duration only then it is a run once setup.
|
||||
// The APRS schedule thread terminates and leaves the radio active.
|
||||
// If duration is TIME_INFINITE then the radio stay active while the thread waits forever.
|
||||
// If duration is TIME_INFINITE then the radio stays active while the thread waits forever.
|
||||
.active = true,
|
||||
.init_delay = TIME_S2I(20),
|
||||
.cycle = TIME_S2I(60 * 10),
|
||||
|
|
|
@ -124,8 +124,8 @@ void usb_cmd_set_trace_level(BaseSequentialStream *chp, int argc, char *argv[])
|
|||
|
||||
void usb_cmd_printPicture(BaseSequentialStream *chp, int argc, char *argv[])
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
/*
|
||||
* Take picture.
|
||||
|
@ -134,40 +134,40 @@ void usb_cmd_printPicture(BaseSequentialStream *chp, int argc, char *argv[])
|
|||
* MSG_RESET = no camera found
|
||||
* MSG_TIMEOUT = capture failed.
|
||||
*/
|
||||
size_t size_sampled;
|
||||
msg_t msg = takePicture(usb_buffer, sizeof(usb_buffer), RES_QVGA,
|
||||
&size_sampled, false);
|
||||
size_t size_sampled;
|
||||
msg_t msg = takePicture(usb_buffer, sizeof(usb_buffer), RES_QVGA,
|
||||
&size_sampled, false);
|
||||
|
||||
// Transmit image via USB
|
||||
if(size_sampled && msg == MSG_OK)
|
||||
{
|
||||
bool start_detected = false;
|
||||
for(uint32_t i=0; i<size_sampled; i++)
|
||||
{
|
||||
// Look for APP0 instead of SOI because SOI is lost sometimes, but we can add SOI easily later on
|
||||
if(!start_detected && usb_buffer[i] == 0xFF && usb_buffer[i+1] == 0xE0) {
|
||||
start_detected = true;
|
||||
TRACE_INFO("DATA > image/jpeg,%d", size_sampled-i+2); // Flag the data on serial output
|
||||
streamPut(chp, 0xFF);
|
||||
streamPut(chp, 0xD8);
|
||||
}
|
||||
if(start_detected)
|
||||
streamPut(chp, usb_buffer[i]);
|
||||
}
|
||||
if(!start_detected)
|
||||
{
|
||||
TRACE_INFO("DATA > image/jpeg,0");
|
||||
TRACE_INFO("DATA > text/trace,no SOI flag found");
|
||||
return;
|
||||
}
|
||||
// Transmit image via USB
|
||||
if(size_sampled)
|
||||
{
|
||||
bool start_detected = false;
|
||||
for(uint32_t i=0; i<size_sampled; i++)
|
||||
{
|
||||
// Look for APP0 instead of SOI because SOI is lost sometimes, but we can add SOI easily later on
|
||||
if(!start_detected && usb_buffer[i] == 0xFF && usb_buffer[i+1] == 0xE0) {
|
||||
start_detected = true;
|
||||
chprintf(chp, "DATA > image/jpeg,%d\r\n", size_sampled-i+2); // Flag the data on serial output
|
||||
streamPut(chp, 0xFF);
|
||||
streamPut(chp, 0xD8);
|
||||
}
|
||||
if(start_detected)
|
||||
streamPut(chp, usb_buffer[i]);
|
||||
}
|
||||
if(!start_detected)
|
||||
{
|
||||
chprintf(chp, "DATA > image/jpeg,0\r\n");
|
||||
chprintf(chp, "DATA > text/trace,no SOI flag found\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
} else if(msg == MSG_RESET) { // Camera error
|
||||
TRACE_INFO("DATA > image,jpeg,0");
|
||||
TRACE_INFO("DATA > error,no camera found");
|
||||
return;
|
||||
} /* MSG_TIMEOUT. */
|
||||
TRACE_INFO("DATA > image,jpeg,0");
|
||||
TRACE_INFO("DATA > error,capture failed");
|
||||
} else if(msg == MSG_RESET) { // Camera error
|
||||
chprintf(chp, "DATA > image,jpeg,0\r\n");
|
||||
chprintf(chp, "DATA > error,no camera found\r\n");
|
||||
return;
|
||||
} /* MSG_TIMEOUT. */
|
||||
chprintf(chp, "DATA > image,jpeg,0\r\n");
|
||||
chprintf(chp, "DATA > error,capture failed\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -386,7 +386,7 @@ static char ssdv_outbits(ssdv_t *s, uint16_t bits, uint8_t length)
|
|||
/* Insert stuffing byte if needed */
|
||||
if(s->out_stuff && b == 0xFF)
|
||||
{
|
||||
s->outbits &= (1 << s->outlen) - 1;
|
||||
s->outbits <<= 8;
|
||||
s->outlen += 8;
|
||||
}
|
||||
}
|
||||
|
@ -413,13 +413,14 @@ static char ssdv_out_jpeg_int(ssdv_t *s, uint8_t rle, int value)
|
|||
|
||||
if(r != SSDV_OK) {
|
||||
TRACE_ERROR("SSDV > jpeg_dht_lookup_symbol: %i (%i:%i)", r, value, rle);
|
||||
return SSDV_ERROR;
|
||||
return(SSDV_ERROR);
|
||||
}
|
||||
|
||||
ssdv_outbits(s, huffbits, hufflen);
|
||||
if(intlen) ssdv_outbits(s, intbits, intlen);
|
||||
|
||||
return(SSDV_OK);
|
||||
r = ssdv_outbits(s, huffbits, hufflen);
|
||||
if(intlen && r == SSDV_OK) {
|
||||
r = ssdv_outbits(s, intbits, intlen);
|
||||
}
|
||||
return(r);
|
||||
}
|
||||
|
||||
static char ssdv_process(ssdv_t *s)
|
||||
|
@ -461,7 +462,6 @@ static char ssdv_process(ssdv_t *s)
|
|||
else r = ssdv_out_jpeg_int(s, 0, 0);
|
||||
/* skip to the next AC part immediately */
|
||||
s->acpart++;
|
||||
if(r != SSDV_OK) return(r);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -494,10 +494,10 @@ static char ssdv_process(ssdv_t *s)
|
|||
s->needbits = symbol & 0x0F;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear processed bits */
|
||||
s->worklen -= width;
|
||||
s->workbits &= (1 << s->worklen) - 1;
|
||||
if(r != SSDV_OK) return(r);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -528,7 +528,6 @@ static char ssdv_process(ssdv_t *s)
|
|||
r = ssdv_out_jpeg_int(s, 0, i - s->dc[s->component]);
|
||||
s->dc[s->component] = i;
|
||||
}
|
||||
if(r != SSDV_OK) return(r);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -547,7 +546,6 @@ static char ssdv_process(ssdv_t *s)
|
|||
r = ssdv_out_jpeg_int(s, 0, i - s->adc[s->component]);
|
||||
s->adc[s->component] = i;
|
||||
}
|
||||
if(r != SSDV_OK) return(r);
|
||||
}
|
||||
}
|
||||
else /* AC */
|
||||
|
@ -559,11 +557,9 @@ static char ssdv_process(ssdv_t *s)
|
|||
{
|
||||
r = ssdv_out_jpeg_int(s, 15, 0);
|
||||
s->accrle -= 16;
|
||||
if(r != SSDV_OK) return(r);
|
||||
}
|
||||
r = ssdv_out_jpeg_int(s, s->accrle, i);
|
||||
s->accrle = 0;
|
||||
if(r != SSDV_OK) return(r);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -572,7 +568,6 @@ static char ssdv_process(ssdv_t *s)
|
|||
{
|
||||
r = ssdv_out_jpeg_int(s, 0, 0);
|
||||
s->accrle = 0;
|
||||
if(r != SSDV_OK) return(r);
|
||||
}
|
||||
else s->accrle += s->acrle + 1;
|
||||
}
|
||||
|
@ -589,8 +584,10 @@ static char ssdv_process(ssdv_t *s)
|
|||
s->workbits &= (1 << s->worklen) - 1;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
} /* End switch on state. */
|
||||
if(s->acpart >= 64)
|
||||
{
|
||||
|
@ -603,9 +600,8 @@ static char ssdv_process(ssdv_t *s)
|
|||
{
|
||||
s->component = s->mcupart - s->ycparts + 1;
|
||||
s->acpart = 0; r = ssdv_out_jpeg_int(s, 0, 0); /* DC */
|
||||
if(r != SSDV_OK) return(SSDV_ERROR);
|
||||
/* Should handle buffer full but doesn't. */
|
||||
s->acpart = 1; r = ssdv_out_jpeg_int(s, 0, 0); /* AC */
|
||||
if(r != SSDV_OK) return(SSDV_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -999,7 +995,7 @@ char ssdv_enc_get_packet(ssdv_t *s)
|
|||
|
||||
/* Skip bytes if necessary */
|
||||
if(s->in_skip) { s->in_skip--; continue; }
|
||||
|
||||
r = SSDV_OK;
|
||||
switch(s->state)
|
||||
{
|
||||
case S_MARKER:
|
||||
|
@ -1116,6 +1112,7 @@ char ssdv_enc_get_packet(ssdv_t *s)
|
|||
/* Have we reached the end of the image data? */
|
||||
if(r == SSDV_EOI) s->state = S_EOI;
|
||||
|
||||
/* Return SSDV_EOI or SSDV_BUFFER_FULL */
|
||||
return(r);
|
||||
}
|
||||
else if(r != SSDV_FEED_ME)
|
||||
|
@ -1129,8 +1126,9 @@ char ssdv_enc_get_packet(ssdv_t *s)
|
|||
case S_EOI:
|
||||
/* Shouldn't reach this point */
|
||||
break;
|
||||
}
|
||||
}
|
||||
} /* End switch on state */
|
||||
if(r == SSDV_BUFFER_FULL) return(r);
|
||||
} /* End while in_len */
|
||||
|
||||
/* Need more data */
|
||||
return(SSDV_FEED_ME);
|
||||
|
@ -1145,14 +1143,19 @@ char ssdv_enc_feed(ssdv_t *s, const uint8_t *buffer, size_t length)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void ssdv_write_marker(ssdv_t *s, uint16_t id, uint16_t length, const uint8_t *data)
|
||||
static char ssdv_write_marker(ssdv_t *s, uint16_t id, uint16_t length, const uint8_t *data)
|
||||
{
|
||||
ssdv_outbits(s, id, 16);
|
||||
if(length > 0)
|
||||
int r;
|
||||
r = ssdv_outbits(s, id, 16);
|
||||
if(length > 0 && r == SSDV_OK)
|
||||
{
|
||||
ssdv_outbits(s, length + 2, 16);
|
||||
while(length--) ssdv_outbits(s, *(data++), 8);
|
||||
if(ssdv_outbits(s, length + 2, 16) != SSDV_OK)
|
||||
return(SSDV_ERROR);
|
||||
do {
|
||||
r = ssdv_outbits(s, *(data++), 8);
|
||||
} while(--length && r == SSDV_OK);
|
||||
}
|
||||
return(length == 0 ? r : SSDV_ERROR);
|
||||
}
|
||||
|
||||
static void ssdv_out_headers(ssdv_t *s)
|
||||
|
@ -1350,6 +1353,7 @@ char ssdv_dec_feed(ssdv_t *s, uint8_t *packet)
|
|||
|
||||
/* Fill the gap left by the missing packet */
|
||||
ssdv_fill_gap(s, s->packet_mcu_id);
|
||||
|
||||
|
||||
/* Skip the bytes of the lost MCU */
|
||||
i = s->packet_mcu_offset;
|
||||
|
|
|
@ -625,7 +625,7 @@ THD_FUNCTION(collectorThread, arg) {
|
|||
TRACE_TAB, time.year, time.month, time.day, time.hour, time.minute, time.day,
|
||||
TRACE_TAB, tp->gps_lat/10000000, (tp->gps_lat > 0 ? 1:-1)*(tp->gps_lat/100)%100000, tp->gps_lon/10000000, (tp->gps_lon > 0 ? 1:-1)*(tp->gps_lon/100)%100000, tp->gps_alt,
|
||||
TRACE_TAB, tp->gps_sats, tp->gps_ttff,
|
||||
TRACE_TAB, tp->adc_vbat/1000, (tp->adc_vbat%1000), tp->adc_vsol/1000, (tp->adc_vsol%1000), tp->pac_pbat,
|
||||
TRACE_TAB, tp->adc_vbat/1000, (tp->adc_vbat%1000), tp->adc_vsol/1000, (tp->adc_vsol%1000), tp->pac_pbat / 10,
|
||||
TRACE_TAB, tp->sen_i1_press/10, tp->sen_i1_press%10, tp->sen_i1_temp/100, tp->sen_i1_temp%100, tp->sen_i1_hum/10, tp->sen_i1_hum%10,
|
||||
TRACE_TAB, tp->gpio & 1, (tp->gpio >> 1) & 1, (tp->gpio >> 2) & 1, (tp->gpio >> 3) & 1,
|
||||
TRACE_TAB, config->call
|
||||
|
|
|
@ -1000,7 +1000,6 @@ static bool send_image_packets(const uint8_t *image,
|
|||
|
||||
case SSDV_EOI:
|
||||
case SSDV_BUFFER_FULL: {
|
||||
//bi += sizeof(pkt);
|
||||
/*
|
||||
* Have a full SSDV buffer to encode and send or an EOI.
|
||||
* Sync byte, CRC and FEC of SSDV not transmitted.
|
||||
|
@ -1036,6 +1035,7 @@ static bool send_image_packets(const uint8_t *image,
|
|||
}
|
||||
|
||||
default: {
|
||||
/* TODO: Check c and handle case of SSDV_ERROR versus other states. */
|
||||
TRACE_ERROR("CAM > Error in image (ssdv_enc_get_packet failed:"
|
||||
" %d at %d of %d)",
|
||||
c, (image_len - ssdv.in_len), image_len);
|
||||
|
@ -1096,7 +1096,7 @@ static bool send_image_packets(const uint8_t *image,
|
|||
&& conf->redundantTx) {
|
||||
/* Wait for packet to be available. */
|
||||
if(chSemWait(&tx_complete) == MSG_RESET)
|
||||
return false;
|
||||
return false;
|
||||
packet_t packet = aprs_encode_data_packet(conf->call, conf->path,
|
||||
'I', pkt_base91);
|
||||
if(packet == NULL) {
|
||||
|
@ -1402,7 +1402,7 @@ THD_FUNCTION(imgThread, arg) {
|
|||
void start_image_thread(img_app_conf_t *conf, const char *name)
|
||||
{
|
||||
thread_t *th = chThdCreateFromHeap(NULL,
|
||||
THD_WORKING_AREA_SIZE(8 * 1024),
|
||||
THD_WORKING_AREA_SIZE(9 * 1024),
|
||||
name, LOWPRIO, imgThread, conf);
|
||||
if(!th) {
|
||||
// Print startup error, do not start watchdog for this thread
|
||||
|
|
Ładowanie…
Reference in New Issue