Esempio n. 1
0
/**
 * Transmit APRS telemetry configuration
 */
uint32_t aprs_encode_telemetry_configuration(uint8_t* message, mod_t mod, telemetryConfig_t type)
{
	char temp[4];
	ax25_t packet;
	packet.data = message;
	packet.max_size = 512; // TODO: replace 512 with real size
	packet.mod = mod;

	ax25_send_header(&packet, APRS_CALLSIGN, APRS_SSID, APRS_PATH); // Header
	ax25_send_byte(&packet, ':'); // Message flag

	// Callsign
	ax25_send_string(&packet, APRS_CALLSIGN);
	ax25_send_byte(&packet, '-');
	chsnprintf(temp, sizeof(temp), "%d", APRS_SSID);
	ax25_send_string(&packet, temp);

	ax25_send_string(&packet, " :"); // Message separator

	switch(type) {
		case CONFIG_PARM:
			ax25_send_string(&packet, "PARM.Battery,Solar,Temp,Charge,Discharge");
			break;
		case CONFIG_UNIT:
			ax25_send_string(&packet, "UNIT.Volt,Volt,degC,mW,mW");
			break;
		case CONFIG_EQNS:
			ax25_send_string(&packet,
				"EQNS."
				"0,.001,0,"
				"0,.001,0,"
				"0,0.1,-100,"
				"0,1,0,"
				"0,1,0"
			);
			break;
		case CONFIG_BITS:
			ax25_send_string(&packet, "BITS.11111111,Pecan Balloon");
			break;
	}

	ax25_send_footer(&packet); // Footer
	nrzi_encode(&packet);
	scramble(&packet);
	
	return packet.size;
}
Esempio n. 2
0
// Exported functions
void aprs_send()
{
  char temp[12];                   // Temperature (int/ext)
  const struct s_address addresses[] = { 
    {D_CALLSIGN, D_CALLSIGN_ID},  // Destination callsign
    {S_CALLSIGN, S_CALLSIGN_ID},  // Source callsign (-11 = balloon, -9 = car)
#ifdef DIGI_PATH1
    {DIGI_PATH1, DIGI_PATH1_TTL}, // Digi1 (first digi in the chain)
#endif
#ifdef DIGI_PATH2
    {DIGI_PATH2, DIGI_PATH2_TTL}, // Digi2 (second digi in the chain)
#endif
  };

  ax25_send_header(addresses, sizeof(addresses)/sizeof(s_address));
  ax25_send_byte('/');                // Report w/ timestamp, no APRS messaging. $ = NMEA raw data
  // ax25_send_string("021709z");     // 021709z = 2nd day of the month, 17:09 zulu (UTC/GMT)
  ax25_send_string(gps_time);         // 170915 = 17h:09m:15s zulu (not allowed in Status Reports)
  ax25_send_byte('h');
  ax25_send_string(gps_aprs_lat);     // Lat: 38deg and 22.20 min (.20 are NOT seconds, but 1/100th of minutes)
  ax25_send_byte('/');                // Symbol table
  ax25_send_string(gps_aprs_lon);     // Lon: 000deg and 25.80 min
  ax25_send_byte('O');                // Symbol: O=balloon, -=QTH
  snprintf(temp, 4, "%03d", (int)(gps_course + 0.5)); 
  ax25_send_string(temp);             // Course (degrees)
  ax25_send_byte('/');                // and
  snprintf(temp, 4, "%03d", (int)(gps_speed + 0.5));
  ax25_send_string(temp);             // speed (knots)
  ax25_send_string("/A=");            // Altitude (feet). Goes anywhere in the comment area
  snprintf(temp, 7, "%06ld", (long)(meters_to_feet(gps_altitude) + 0.5));
  ax25_send_string(temp);
  ax25_send_string("/Ti=");
  snprintf(temp, 6, "%d", sensors_int_lm60());
  ax25_send_string(temp);
  ax25_send_string("/Te=");
  snprintf(temp, 6, "%d", sensors_ext_lm60());
  ax25_send_string(temp);
  ax25_send_string("/V=");
  snprintf(temp, 6, "%d", sensors_vin());
  ax25_send_string(temp);
  ax25_send_byte(' ');
  ax25_send_string(APRS_COMMENT);     // Comment
  ax25_send_footer();

  ax25_flush_frame();                 // Tell the modem to go
}
Esempio n. 3
0
void tweet_send(const char *TWEET_MESSAGE)
{
  char temp[12];                   // Temperature (int/ext) 
  const struct s_address addresses[] = { 
    {D2_CALLSIGN, D2_CALLSIGN_ID},  // Destination callsign
    {S2_CALLSIGN, S2_CALLSIGN_ID},  // Source callsign (-11 = balloon, -9 = car)
#ifdef DIGI_PATH1
    {DIGI_PATH1, DIGI_PATH1_TTL}, // Digi1 (first digi in the chain)
#endif
#ifdef DIGI_PATH2
    {DIGI_PATH2, DIGI_PATH2_TTL}, // Digi2 (second digi in the chain)
#endif
  };
 
  ax25_send_header(addresses, sizeof(addresses)/sizeof(s_address));
//  ax25_send_string(":KJ6DYP-7 :");
  ax25_send_string(":73S      :");
  ax25_send_string(TWEET_MESSAGE);
  ax25_send_footer();
  ax25_flush_frame();                 // Tell the modem to go
}
Esempio n. 4
0
uint32_t aprs_encode_image(uint8_t* message, mod_t mod, uint8_t *image, size_t size)
{
	ax25_t packet;
	packet.data = message;
	packet.max_size = 512; // TODO: replace 512 with real size
	packet.mod = mod;

	// Encode APRS header
	ax25_send_header(&packet, APRS_CALLSIGN, APRS_SSID, NULL);
	ax25_send_string(&packet, "{{I");

	// Encode image message
	for(uint16_t i=0; i<size; i++)
		ax25_send_byte(&packet, image[i]);

	// Send footer
	ax25_send_footer(&packet);
	nrzi_encode(&packet);
	scramble(&packet);

	return packet.size;
}
Esempio n. 5
0
/**
 * Transmit APRS position packet. The comments are filled with:
 * - Static comment (can be set in config.h)
 * - Battery voltage in mV
 * - Solar voltage in mW (if tracker is solar-enabled)
 * - Temperature in Celcius
 * - Air pressure in Pascal
 * - Number of satellites being used
 * - Number of cycles where GPS has been lost (if applicable in cycle)
 */
uint32_t aprs_encode_position(uint8_t* message, mod_t mod, trackPoint_t *trackPoint)
{
	char temp[22];
	ptime_t date = trackPoint->time;
	ax25_t packet;
	packet.data = message;
	packet.max_size = 512; // TODO: replace 512 with real size
	packet.mod = mod;

	ax25_send_header(&packet, APRS_CALLSIGN, APRS_SSID, APRS_PATH);
	ax25_send_byte(&packet, '/');                // Report w/ timestamp, no APRS messaging. $ = NMEA raw data

	// 170915 = 17h:09m:15s zulu (not allowed in Status Reports)
	chsnprintf(temp, sizeof(temp), "%02d%02d%02dh", date.hour, date.minute, date.second);
	ax25_send_string(&packet, temp);

	// Latitude
	uint32_t y = 380926 * (90 - trackPoint->gps_lat/10000000.0);
	uint32_t y3  = y   / 753571;
	uint32_t y3r = y   % 753571;
	uint32_t y2  = y3r / 8281;
	uint32_t y2r = y3r % 8281;
	uint32_t y1  = y2r / 91;
	uint32_t y1r = y2r % 91;

	// Longitude
	uint32_t x = 190463 * (180 + trackPoint->gps_lon/10000000.0);
	uint32_t x3  = x   / 753571;
	uint32_t x3r = x   % 753571;
	uint32_t x2  = x3r / 8281;
	uint32_t x2r = x3r % 8281;
	uint32_t x1  = x2r / 91;
	uint32_t x1r = x2r % 91;

	// Altitude
	uint32_t a = logf(METER_TO_FEET(trackPoint->gps_alt)) / logf(1.002f);
	uint32_t a1  = a / 91;
	uint32_t a1r = a % 91;

	uint8_t gpsFix = trackPoint->gps_lock ? GSP_FIX_CURRENT : GSP_FIX_OLD;
	uint8_t src = NMEA_SRC_GGA;
	uint8_t origin = ORIGIN_PICO;

	temp[0]  = SYM_GET_TABLE(APRS_SYMBOL);
	temp[1]  = y3+33;
	temp[2]  = y2+33;
	temp[3]  = y1+33;
	temp[4]  = y1r+33;
	temp[5]  = x3+33;
	temp[6]  = x2+33;
	temp[7]  = x1+33;
	temp[8]  = x1r+33;
	temp[9]  = SYM_GET_SYMBOL(APRS_SYMBOL);
	temp[10] = a1+33;
	temp[11] = a1r+33;
	temp[12] = ((gpsFix << 5) | (src << 3) | origin) + 33;
	temp[13] = 0;

	ax25_send_string(&packet, temp);

	// Comments
	ax25_send_string(&packet, "SATS ");
	chsnprintf(temp, sizeof(temp), "%d", trackPoint->gps_sats);
	ax25_send_string(&packet, temp);

	ax25_send_string(&packet, " TTFF ");
	chsnprintf(temp, sizeof(temp), "%d", trackPoint->gps_ttff);
	ax25_send_string(&packet, temp);
	ax25_send_string(&packet, "sec");

	// GPS Loss counter
	if(!trackPoint->gps_lock)
	{
		ax25_send_string(&packet, " GPS LOSS ");
		chsnprintf(temp, sizeof(temp), "%d", ++loss_of_gps_counter);
		ax25_send_string(&packet, temp);
	} else {
		loss_of_gps_counter = 0;
	}

	temp[2] = 0;

	ax25_send_byte(&packet, '|');

	// Sequence ID
	uint32_t t = trackPoint->id & 0x1FFF;
	temp[0] = t/91 + 33;
	temp[1] = t%91 + 33;
	ax25_send_string(&packet, temp);

	// Battery voltage
	t = trackPoint->adc_battery;
	temp[0] = t/91 + 33;
	temp[1] = t%91 + 33;
	ax25_send_string(&packet, temp);

	// Solar voltage
	t = trackPoint->adc_solar;
	temp[0] = t/91 + 33;
	temp[1] = t%91 + 33;
	ax25_send_string(&packet, temp);

	// Temperature
	t = trackPoint->air_temp/10 + 1000;
	temp[0] = t/91 + 33;
	temp[1] = t%91 + 33;
	ax25_send_string(&packet, temp);

	// Battery charge
	t = trackPoint->adc_charge;
	temp[0] = t/91 + 33;
	temp[1] = t%91 + 33;
	ax25_send_string(&packet, temp);

	// Battery discharge
	t = trackPoint->adc_discharge;
	temp[0] = t/91 + 33;
	temp[1] = t%91 + 33;
	ax25_send_string(&packet, temp);

	ax25_send_byte(&packet, '|');

	ax25_send_footer(&packet);
	nrzi_encode(&packet);
	scramble(&packet);

	return packet.size;
}