Subversion Repositories Projects

Compare Revisions

Ignore whitespace Rev 2104 → Rev 2105

/RaspberryPi/ExPlat/ExPlat
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/RaspberryPi/ExPlat/ExPlat
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/RaspberryPi/ExPlat/Makefile
0,0 → 1,23
OBJ = main.o gpio.o uart.o processing.o flightcontrol.o timer.o flowcam.o
DEPS = main.h gpio.h uart.h types.h processing.h flightcontrol.h timer.h flowcam.h
LIBS =
CFLAGS = -std=c99 -Wall -export-dynamic -L/usr/lib/python2.7/config -lpython2.7 -lm -ldl -lutil -lpthread
CC = gcc
EXTENSION = .c
 
#define a rule that applies to all files ending in the .o suffix, which says that the .o file depends upon the .c version of the file and all the .h files included in the DEPS macro. Compile each object file
%.o: %$(EXTENSION) $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
 
#Combine them into the output file
#Set your desired exe output file name here
all: ExPlat clean
 
ExPlat: $(OBJ)
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
 
#Cleanup
.PHONY: clean
 
clean:
rm -f *.o *~ core *~
/RaspberryPi/ExPlat/flightcontrol.c
0,0 → 1,173
#include "main.h"
#include "flightcontrol.h"
 
int reference_altitude; //Regelgröße
int reference_accz; //Regelgröße D-Anteil
int reference_flow_x;
int reference_flow_y;
 
int altitude_differenz; //Regelabweichung
int altitude_differenz_sum = 0; //I-Glied
int xDirection_differenz_sum = 0;
int yDirection_differenz_sum = 0;
 
int altitude_old;
int altitude_velocity;
int xDirection_old;
int xDirection_velocity;
int yDirection_old;
int yDirection_velocity;
 
float gas_correction_dpart;
float gas_correction_ipart = 0.0;
float gas_correction_ppart;
float gas_correction_final;
float nick_correction_dpart;
float nick_correction_ipart = 0.0;
float nick_correction_ppart;
float nick_correction_final;
float roll_correction_dpart;
float roll_correction_ipart = 0.0;
float roll_correction_ppart;
float roll_correction_final;
 
float pFactorGas = 0.3; //Verstärkungsfaktor P
float iFactorGas = 0.02; //Verstärkungsfaktor I
float dFactorGas = 0.3; //Verstärkungsfaktor D
float pFactorNick = 0.2; //Verstärkungsfaktor P
float iFactorNick = 0.02; //Verstärkungsfaktor I
float dFactorNick = 0.3; //Verstärkungsfaktor D
float pFactorRoll = 0.2; //Verstärkungsfaktor P
float iFactorRoll = 0.02; //Verstärkungsfaktor I
float dFactorRoll = 0.3; //Verstärkungsfaktor D
 
//>> Performing Flight Correction
//------------------------------------------------------------------------------------------------------
void perform_flight_correction(){
reference_altitude = (int)(optical_flow_values.ground_distance*1000); //Regelgröße in mm
reference_flow_x += (int)(optical_flow_values.flow_comp_m_x*1000);
reference_flow_y += (int)(optical_flow_values.flow_comp_m_y*1000);
altitude_differenz = STARTING_ALTITUDE - reference_altitude; //Regelabweichung in mm
 
if(reference_altitude != altitude_old){
altitude_velocity = (reference_altitude - altitude_old) / 0.1;
}
if(reference_flow_x != xDirection_old){
xDirection_velocity = (reference_flow_x - xDirection_old) / 0.1;
}
if(reference_flow_y != yDirection_old){
yDirection_velocity = (reference_flow_y - yDirection_old) / 0.1;
}
 
if(altitude_differenz_sum < 10000 && altitude_differenz_sum > -10000){
altitude_differenz_sum += altitude_differenz * 0.1;
if(altitude_differenz_sum > 9999){altitude_differenz_sum = 9999;}else
if(altitude_differenz_sum < -9999){altitude_differenz_sum = -9999;}
}
if(xDirection_differenz_sum < 1000 && xDirection_differenz_sum > -1000){
xDirection_differenz_sum += reference_flow_x;
if(xDirection_differenz_sum > 9999){xDirection_differenz_sum = 9999;}else
if(xDirection_differenz_sum < -9999){xDirection_differenz_sum = -9999;}
}
if(yDirection_differenz_sum < 1000 && yDirection_differenz_sum > -1000){
yDirection_differenz_sum += reference_flow_y;
if(yDirection_differenz_sum > 9999){yDirection_differenz_sum = 9999;}else
if(yDirection_differenz_sum < -9999){yDirection_differenz_sum = -9999;}
}
 
//////////////////////////////////////////////////////////////////////////
// PID Regelung Gas
gas_correction_ipart = iFactorGas * altitude_differenz_sum;
gas_correction_dpart = dFactorGas * altitude_velocity *-1;
gas_correction_ppart = pFactorGas * altitude_differenz;
 
gas_correction_final = (gas_correction_ppart + gas_correction_dpart + gas_correction_ipart) / 10;
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// PID Regelung Nick
nick_correction_ipart = iFactorNick * yDirection_differenz_sum;
nick_correction_dpart = dFactorNick * yDirection_velocity;
nick_correction_ppart = pFactorNick * reference_flow_y;
 
nick_correction_final = (nick_correction_ppart + nick_correction_dpart + nick_correction_ipart) / -10;
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// PID Regelung Roll
roll_correction_ipart = iFactorRoll * xDirection_differenz_sum;
roll_correction_dpart = dFactorRoll * xDirection_velocity;
roll_correction_ppart = pFactorRoll * reference_flow_x;
 
roll_correction_final = (roll_correction_ppart + roll_correction_dpart + roll_correction_ipart) / -10;
//////////////////////////////////////////////////////////////////////////
//printf("Final: %f PPART: %f DPART: %f\n", nick_correction_final, nick_correction_ppart, nick_correction_dpart);
 
//////////////////////////////////////////////////////////////////////////
// Set Limits
if(gas_correction_final >= 20){
fc_correction_data.Gas = 20;
}else if(gas_correction_final <= -20){
fc_correction_data.Gas = -20;
}else{
fc_correction_data.Gas = gas_correction_final;
}
if(nick_correction_final >= 20){
fc_correction_data.Nick = 20;
}else if(nick_correction_final <= -20){
fc_correction_data.Nick = -20;
}else{
fc_correction_data.Nick = nick_correction_final;
}
if(roll_correction_final >= 20){
fc_correction_data.Roll = 20;
}else if(roll_correction_final <= -20){
fc_correction_data.Roll = -20;
}else{
fc_correction_data.Roll = roll_correction_final;
}
 
//printf("%d\n", reference_altitude/10);
printf("Final: %f PPART: %f DPART: %f IPART: %f Gas Correction: %d\n", gas_correction_final, gas_correction_ppart, gas_correction_dpart, gas_correction_ipart, fc_correction_data.Gas );
//printf("Final: %f PPART: %f DPART: %f IPART: %f Gas Correction: %d\n", nick_correction_final, nick_correction_ppart, nick_correction_dpart, nick_correction_ipart, fc_correction_data.Nick );
fc_correction_data.Gas = 0;
//fc_correction_data.Roll = 0;
//fc_correction_data.Nick = 0;
 
 
altitude_old = reference_altitude;
xDirection_old = reference_flow_x;
yDirection_old = reference_flow_y;
}
 
//>> Transmitting Correction Data
//------------------------------------------------------------------------------------------------------
u8 *flight_values_stream;
serial_data_struct data_package_flightcontrol;
void transmit_flight_data(){
flight_values_stream = (unsigned char *) &fc_correction_data;
//printf("Correction: %d\n", fc_correction_data.Gas);
for (int i = 0; i < sizeof(struct str_fc_correction_data); ++i)
{
data_package_flightcontrol.data[i] = flight_values_stream[i];
}
create_serial_frame(1, 'b', sizeof(struct str_fc_correction_data), &data_package_flightcontrol);
//printf("%s\n", data_package_flightcontrol.txrxdata);
transmit_data(TO_KOPTER, &data_package_flightcontrol);
}
 
//>> Resetting Flow and Altitude Values
//------------------------------------------------------------------------------------------------------
void reset_reference_values(){
reference_flow_x = 0.0;
reference_flow_y = 0.0;
reference_altitude = 0.0;
}
 
//>> Initializing flightcontrol
//------------------------------------------------------------------------------------------------------
void flightcontrol_init(){
fc_correction_data.Nick = 0;
fc_correction_data.Roll = 0;
fc_correction_data.Gier = 0;
fc_correction_data.Gas = 0;
fc_correction_data.Config = EC_VALID | EC_GAS_ADD | EC_IGNORE_RC; //Ignore Remote Control
}
/RaspberryPi/ExPlat/flightcontrol.h
0,0 → 1,74
#ifndef _FLIGHTCONTROL_H
#define _FLIGHTCONTROL_H
 
#define EC_VALID 0x01 //only valid if this is 1
#define EC_GAS_ADD 0x02 //if 1 -> use the GAS Value not as MAX
#define EC_IGNORE_RC 0x80 //if 1 -> for Flying without RC-Control
 
#define STARTING_ALTITUDE 1000
#define MAX_ALTITUDE 3000
#define MAX_CLIMBING_SPEED 50
#define STARTING_THRUST 10
 
extern void perform_flight_correction();
extern void reset_reference_values();
extern void flightcontrol_init();
extern void transmit_flight_data();
extern void flightcontrol_timekeeper();
 
struct str_3d_data
{
int16 AngleNick;
int16 AngleRoll;
int16 Heading;
u8 StickNick;
u8 StickRoll;
u8 StickYaw;
u8 StickGas;
int16 Altimeter;
int16 AccZ;
};
struct str_3d_data flight_data;
 
struct str_configuration
{
u8 channel_gas;
u8 channel_gier;
u8 channel_nick;
u8 channel_roll;
u8 channel_heightControl;
u8 channel_autostart;
u8 channel_gps;
u8 channel_carefree;
u8 dynamicPositionHold;
};
struct str_configuration config_data;
 
struct str_flightcontrol_values
{
u8 value_gas;
u8 value_gier;
u8 value_nick;
u8 value_roll;
u8 value_heightControl;
u8 value_autostart;
u8 value_gps;
u8 value_carefree;
u8 value_dynamicPositionHold;
};
struct str_flightcontrol_values fc_values;
 
struct str_fc_correction_data
{
signed char Nick;
signed char Roll;
signed char Gier;
signed char Gas;
unsigned char Frame;
unsigned char Config;
unsigned char free;
};
 
struct str_fc_correction_data fc_correction_data;
 
#endif //_FLIGHTCONTROL_H
/RaspberryPi/ExPlat/flowcam.c
0,0 → 1,63
#include "main.h"
#include "flowcam.h"
 
pthread_t piCamThread;
char* indata = NULL;
PyObject *pName, *pModule, *pDict, *pFunc, *pFunc2;
 
//>> Get Motion Vector Data from mmap
//------------------------------------------------------------------------------------------------------
void get_flowcam_values(){
PiCamMoVector = atoi(indata); //PiCam Motion Vectors
printf("MAIN: %d\n", PiCamMoVector);
}
 
//>> Call Function in Python Program
//------------------------------------------------------------------------------------------------------
void *ThreadProc()
{
if(PyCallable_Check(pFunc))
{
PyObject_CallObject(pFunc, NULL);
}else{
PyErr_Print();
}
 
//Clean up (Programm will never reach this Part)
Py_DECREF(pModule);
Py_DECREF(pName);
 
Py_Finalize();
printf("piCamThread is finishing...\n");
}
 
//>> Create MMAP, Python Object and start Thread
//------------------------------------------------------------------------------------------------------
void flowcam_init(){
//////////////////////////////////////////////////////////////////////////
// Create a MMAP
int fd;
if((fd = open("/home/pi/ExPlat/input.dat", O_RDWR)) == -1)
{
printf("Couldn't open 'input.data'\n");
}
indata = mmap( NULL, 1024, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if(indata != NULL)
{
printf("Wrapper has created a MMAP for file 'input.data'\n");
}
//////////////////////////////////////////////////////////////////////////
 
char *script = "motionVector";
char *functionUse = "get_values";
Py_Initialize();
pName = PyString_FromString(script);
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append(\"/home/pi/ExPlat\")");
pModule = PyImport_Import(pName);
pDict = PyModule_GetDict(pModule);
pFunc = PyDict_GetItemString(pDict, functionUse);
 
// POSIX code
pthread_create( &piCamThread, NULL, ThreadProc, NULL);
}
/RaspberryPi/ExPlat/flowcam.h
0,0 → 1,10
#ifndef _FLOWCAM_H
#define _FLOWCAM_H
 
extern void flowcam_init();
extern void get_flowcam_values();
 
volatile int PiCamMoVector;
 
 
#endif //_FLOWCAM_H
/RaspberryPi/ExPlat/gpio.c
0,0 → 1,98
#include "main.h"
#include "gpio.h"
 
 
struct timeval startTime; //Times needed for calculating Distance
struct timeval travelTime;
 
// IO Acces
struct bcm2835_peripheral {
unsigned long addr_p;
int mem_fd;
void *map;
volatile unsigned int *addr;
};
struct bcm2835_peripheral gpio = {GPIO_BASE};
 
 
//>> Create MMAP for GPIO
//------------------------------------------------------------------------------------------------------
int map_peripheral(struct bcm2835_peripheral *p)
{
// Open /dev/mem
if ((p->mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
printf("Failed to open /dev/mem, try checking permissions.\n");
return -1;
}
p->map = mmap(
NULL,
BLOCK_SIZE,
PROT_READ|PROT_WRITE,
MAP_SHARED,
p->mem_fd,
p->addr_p
);
if (p->map == MAP_FAILED) {
perror("mmap");
return -1;
}
p->addr = (volatile unsigned int *)p->map;
return 0;
}
void unmap_peripheral(struct bcm2835_peripheral *p) {
munmap(p->map, BLOCK_SIZE);
close(p->mem_fd);
}
 
//>> Funktion for short buzzing Sound
//------------------------------------------------------------------------------------------------------
void buzzer_short(int seq){
INP_GPIO(4);
OUT_GPIO(4);
for (int i = 0; i < seq; ++i)
{
if(seq > 1){usleep(50000);}
GPIO_SET = 1 << 4;
usleep(50000);
GPIO_CLR = 1 << 4;
}
}
 
//>> Calculate Distance with external sonar
//------------------------------------------------------------------------------------------------------
int calculate_distance(){
int distanceTemp;
int loopbreaker = 10000; //Breaks the first loop in case it gets stuck (which happens from time to time if the Objekt facing the sensor is too close)
GPIO_SET = 1 << ULTRA_TRIGGER;
usleep(10);
GPIO_CLR = 1 << ULTRA_TRIGGER;
 
while(!(GPIO_READ(ULTRA_ECHO)))
{
loopbreaker--;
if(!loopbreaker){break;}
}
gettimeofday(&startTime, NULL);
 
while((GPIO_READ(ULTRA_ECHO)))
gettimeofday(&travelTime, NULL);
 
loopbreaker = 0;
distanceTemp = (travelTime.tv_usec - startTime.tv_usec) / 58;
return distanceTemp;
}
 
//>> Initialize GPIO
//------------------------------------------------------------------------------------------------------
void gpio_init(){
if(map_peripheral(&gpio) == -1)
{
printf("Failed to map the physical GPIO registers into the virtual memory space.\n");
}
 
INP_GPIO(ULTRA_ECHO);
OUT_GPIO(ULTRA_TRIGGER);
GPIO_CLR = 1 << ULTRA_TRIGGER;
sleep(1);
}
/RaspberryPi/ExPlat/gpio.h
0,0 → 1,26
#ifndef _GPIO_H
#define _GPIO_H
 
#define BCM2708_PERI_BASE 0x20000000
#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) // GPIO controller
#define BLOCK_SIZE (4*1024)
 
extern struct bcm2835_peripheral gpio;
 
//>> Makros for reading and writing GPIO registers
//------------------------------------------------------------------------------------------------------
#define INP_GPIO(g) *(gpio.addr + ((g)/10)) &= ~(7<<(((g)%10)*3))
#define OUT_GPIO(g) *(gpio.addr + ((g)/10)) |= (1<<(((g)%10)*3))
#define SET_GPIO_ALT(g,a) *(gpio.addr + (((g)/10))) |= (((a)<=3?(a) + 4:(a)==4?3:2)<<(((g)%10)*3))
#define GPIO_SET *(gpio.addr + 7) // sets bits which are 1 ignores bits which are 0
#define GPIO_CLR *(gpio.addr + 10) // clears bits which are 1 ignores bits which are 0
#define GPIO_READ(g) *(gpio.addr + 13) &= (1<<(g))
 
#define ULTRA_ECHO 24
#define ULTRA_TRIGGER 23
 
extern void gpio_init();
extern void buzzer_short(int seq);
extern int calculate_distance();
 
#endif //_GPIO_H
/RaspberryPi/ExPlat/main.c
0,0 → 1,46
#include "main.h"
 
serial_data_struct data_package_receive_kopter; //Data Package for Kopter Data
serial_data_struct data_package_receive_computer; //Data Package for Computer Data
serial_data_struct data_package_flow; //Data Package for Flow Data
 
int tmp = 0;
int main(void){
gpio_init();
uart_init();
processing_init();
timer_init();
flightcontrol_init();
//flowcam_init(); //Uncomment for use of Raspberry Camera Module
reset_reference_values();
 
for (;;)
{
reset_timer();
 
//////////////////////////////////////////////////////////////////////////
// Request Data from Kopter, renew subscribtion every 2 Seconds
if(interval_in_sec(2)){
request_to_kopter(GET_ANALOG_DATA);
//request_to_kopter(GET_3D_DATA);
}
 
//////////////////////////////////////////////////////////////////////////
// Receive Data from Kopter and computer at 200Hz
if(interval_in_msec(5)){
//receive_data_from_computer(&data_package_receive_computer, 0);
receive_data_from_kopter(&data_package_receive_kopter);
}
 
//////////////////////////////////////////////////////////////////////////
// Receive Data from Flow Module and Perform Flight Correction at 200Hz
if(interval_in_msec(5)){
receive_data_from_flow(&data_package_flow);
transmit_flight_data();
}
//if(interval_in_sec(10)){reset_reference_values();}
//if(interval_in_msec(50)){get_distance();}
//if(interval_in_msec(5)){get_flowcam_values();}
}
}
/RaspberryPi/ExPlat/main.h
0,0 → 1,29
#ifndef _MAIN_H
#define _MAIN_H
 
#include </usr/include/python2.7/Python.h>
//#include <stdio.h> //included in python
//#include <string.h> //included in python
#include <stdint.h>
#include <termios.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/time.h>
#include <linux/i2c-dev.h>
#include <pthread.h>
#include "types.h"
#include "uart.h"
#include "gpio.h"
#include "processing.h"
#include "timer.h"
#include "flightcontrol.h"
#include "flowcam.h"
 
//extern void usleep(int);
volatile int Motors_On;
 
volatile u8 global_temp;
 
#endif //_MAIN_H
/RaspberryPi/ExPlat/motionVector.py
0,0 → 1,40
import numpy as np
#np.set_printoptions(threshold=np.nan)
import picamera
import picamera.array
import sys
import os
import time
import mmap
 
##>> Gain access to MMAP
##------------------------------------------------------------------------------------------------------
INDATAFILENAME = '/home/pi/ExPlat/input.dat'
LENGTHDATAMAP = 1024
inDataFile = open(INDATAFILENAME, 'r+')
inDataNo = inDataFile.fileno()
inDataMap = mmap.mmap(inDataNo, LENGTHDATAMAP, access=mmap.ACCESS_WRITE)
s = 0;
 
##>> Analyze Numpy Array and Print Motion Vector Data
##------------------------------------------------------------------------------------------------------
class AnalyzeArray(picamera.array.PiMotionAnalysis):
def analyse(self, a):
global s
global inDataMap
s += a[20,15][0]
#print s
inDataMap.seek(0)
inDataMap.write('%d' %s + '\n')
 
##>> Start Capture and call AnalyzeArray after every frame
##------------------------------------------------------------------------------------------------------
def get_values():
with picamera.PiCamera() as camera:
with AnalyzeArray(camera) as output:
camera.resolution = (640, 480)
camera.framerate = (20, 1)
camera.start_recording(
'/dev/null', format='h264', motion_output=output)
camera.wait_recording(0)
camera.stop_recording()
/RaspberryPi/ExPlat/processing.c
0,0 → 1,374
#include "main.h"
#include "processing.h"
#include "flightcontrol.h"
 
int tmpcount = 0;
 
//>> Pointers for converting Bytes into other Datatypes
//------------------------------------------------------------------------------------------------------
u8 *flow_x_ptr = (u8 *) &optical_flow_values.flow_comp_m_x;
u8 *flow_y_ptr = (u8 *) &optical_flow_values.flow_comp_m_y;
u8 *distance_ptr = (u8 *) &optical_flow_values.ground_distance;
 
u8 *integrated_x_ptr = (u8 *) &optical_flow_rad.integrated_x;
u8 *integrated_y_ptr = (u8 *) &optical_flow_rad.integrated_y;
u8 *integrated_xgyro_ptr = (u8 *) &optical_flow_rad.integrated_xgyro;
u8 *integrated_ygyro_ptr = (u8 *) &optical_flow_rad.integrated_ygyro;
u8 *integrated_zgyro_ptr = (u8 *) &optical_flow_rad.integrated_zgyro;
u8 *distance_rad_ptr = (u8 *) &optical_flow_rad.distance;
 
u8 *gyroz_ptr = (u8 *) &optical_flow_values.gyroz;
 
//>> Convert incoming Flow Array to Datatypes
//------------------------------------------------------------------------------------------------------
void process_flow_data(serial_data_struct* pdata_package_flow_process){
if(pdata_package_flow_process->msg_id == 100){
for (int i = 0; i < 8; ++i)
{
optical_flow_values.time_usec = (optical_flow_values.time_usec<<8) + pdata_package_flow_process->collecting_data[13-i];
}
for (int i = 0; i < 4; ++i)
{
flow_x_ptr[i] = pdata_package_flow_process->collecting_data[14+i];
flow_y_ptr[i] = pdata_package_flow_process->collecting_data[18+i];
distance_ptr[i] = pdata_package_flow_process->collecting_data[22+i];
}
optical_flow_values.flow_x = (optical_flow_values.flow_x<<8) + pdata_package_flow_process->collecting_data[27];
optical_flow_values.flow_x = (optical_flow_values.flow_x<<8) + pdata_package_flow_process->collecting_data[26];
optical_flow_values.flow_y = (optical_flow_values.flow_y<<8) + pdata_package_flow_process->collecting_data[29];
optical_flow_values.flow_y = (optical_flow_values.flow_y<<8) + pdata_package_flow_process->collecting_data[28];
optical_flow_values.sensor_id = pdata_package_flow_process->collecting_data[30];
optical_flow_values.quality = pdata_package_flow_process->collecting_data[31];
}else if(pdata_package_flow_process->msg_id == 106){
for (int i = 0; i < 8; ++i)
{
optical_flow_rad.time_usec = (optical_flow_rad.time_usec<<8) + pdata_package_flow_process->collecting_data[13-i];
}
for (int i = 0; i < 4; ++i)
{
optical_flow_rad.integration_time_us = (optical_flow_rad.integration_time_us<<8) + pdata_package_flow_process->collecting_data[17-i];
integrated_x_ptr[i] = pdata_package_flow_process->collecting_data[18+i];
integrated_y_ptr[i] = pdata_package_flow_process->collecting_data[22+i];
integrated_xgyro_ptr[i] = pdata_package_flow_process->collecting_data[26+i];
integrated_ygyro_ptr[i] = pdata_package_flow_process->collecting_data[30+i];
integrated_zgyro_ptr[i] = pdata_package_flow_process->collecting_data[34+i];
optical_flow_rad.time_delta_distance_us = (optical_flow_rad.time_delta_distance_us<<8) + pdata_package_flow_process->collecting_data[41-i];
distance_rad_ptr[i] = pdata_package_flow_process->collecting_data[42+i];
}
for (int i = 0; i < 2; ++i)
{
optical_flow_rad.temperature = (optical_flow_rad.temperature<<8) + pdata_package_flow_process->collecting_data[47-i];
}
optical_flow_rad.sensor_id = pdata_package_flow_process->collecting_data[48];
optical_flow_rad.quality = pdata_package_flow_process->collecting_data[49];
}else if(pdata_package_flow_process->msg_id == 250){
for (int i = 0; i < 4; ++i)
{
gyroz_ptr[i] = pdata_package_flow_process->collecting_data[18+i];
}
}
}
 
//>> Process NMEA Data from GPS Modul
//------------------------------------------------------------------------------------------------------
char nmeaMsg[5];
char nmeaMsgValue[20];
void process_gps_data(serial_data_struct* pdata_package_gps_process){
if (pdata_package_gps_process->position_package > 0)
{
for (int i = 1; i < 6; ++i){nmeaMsg[i-1] = pdata_package_gps_process->gps_data[0][i];}
}
for (int i = 0; i < sizeof(pdata_package_gps_process->gps_data[pdata_package_gps_process->position_package]); ++i)
{
nmeaMsgValue[i] = pdata_package_gps_process->gps_data[pdata_package_gps_process->position_package][i];
}
if(!strcmp(nmeaMsg, "GLGSV")) //GLONASS (elevation, azimuth, CNR)
{
 
}else if (!strcmp(nmeaMsg, "GNGLL")) //Position, Time, Fix
{
}else if (!strcmp(nmeaMsg, "GNRMC")) //Time, Date, Position, Course, Speed
{
gps_value_struct.latitude = strtof(nmeaMsgValue, NULL);
printf("%d\n", sizeof(pdata_package_gps_process->gps_data[0]));
}else if (!strcmp(nmeaMsg, "GNVTG")) //Course, Speed relative to ground
{
}else if (!strcmp(nmeaMsg, "GNGGA")) //Time, Position, Fix
{
}else if (!strcmp(nmeaMsg, "GNGSA")) //Satelite ID
{
}else if (!strcmp(nmeaMsg, "GPGSV")) //GPS (elevation, azimuth, CNR)
{
 
}
}
 
 
//>> Add Sensor Lables to the serial data stream to appear in the MikroKopter Tool
//------------------------------------------------------------------------------------------------------
void add_sensor_lables(serial_data_struct* pdata_package_add_lables){
u8 lable[17] = "RaspPi Sensor ";
switch(pdata_package_add_lables->data[0])
{
case 16:
for (int u = 1; u < 17; ++u)
{
pdata_package_add_lables->data[u] = lable[u-1];
}
pdata_package_add_lables->data[14] = 49; //Number of the Lable (RaspPi Sensor1)
break;
case 17:
for (int u = 1; u < 17; ++u)
{
pdata_package_add_lables->data[u] = lable[u-1];
}
pdata_package_add_lables->data[14] = 50; //(RaspPi Sensor2)
break;
case 18:
for (int u = 1; u < 17; ++u)
{
pdata_package_add_lables->data[u] = lable[u-1];
}
pdata_package_add_lables->data[14] = 51; //(RaspPi Sensor3)
break;
case 19:
for (int u = 1; u < 17; ++u)
{
pdata_package_add_lables->data[u] = lable[u-1];
}
pdata_package_add_lables->data[14] = 52; //(RaspPi Sensor4)
break;
}
}
 
//>> Add Sensor Data to the serial data stream to appear in the MikroKopter Tool
//------------------------------------------------------------------------------------------------------
void add_sensor_data(serial_data_struct* pdata_package_add_data){
//pdata_package_add_data->data[34] = optical_flow_values.gyroz;
/*
pdata_package_add_data->data[36] = 11;
pdata_package_add_data->data[38] = Distance;
pdata_package_add_data->data[40] = 11;
*/
 
int tmpdata = (pdata_package_add_data->data[14] + 255*pdata_package_add_data->data[15]) -721;
flight_data.AccZ = tmpdata;
printf("%d\n", flight_data.AccZ);
}
 
//>> Get the distance from the ultrasonic sensor module
//------------------------------------------------------------------------------------------------------
u16 average1 = 0;
u8 average2 = 0;
u16 distance_value;
void get_distance(){
distance_value = calculate_distance();
if(distance_value < 300 && distance_value > 0){
average1 += distance_value;
average2++;
if(average2 == 4){
average1 /= 4;
Distance = average1;
printf("DISTANZ: %d\n", Distance);
average1 = 0;
average2 = 0;
}
}
}
 
//>> This Function reads the String containing the Configuration
//------------------------------------------------------------------------------------------------------
void read_configuration(serial_data_struct* pdata_package_config){
config_data.channel_gas = pdata_package_config->data[4];
config_data.channel_gier = pdata_package_config->data[5];
config_data.channel_nick = pdata_package_config->data[2];
config_data.channel_roll = pdata_package_config->data[3];
config_data.channel_heightControl = pdata_package_config->data[17];
config_data.channel_autostart = pdata_package_config->data[114];
config_data.channel_gps = pdata_package_config->data[82];
config_data.channel_carefree = pdata_package_config->data[101];
config_data.dynamicPositionHold = pdata_package_config->data[123];
u8 *tmpData = (unsigned char *) &config_data;
for (int i = 0; i < 9; ++i)
{
printf("%d \n", tmpData[i]);
}
}
 
//>> Assign FlightCtrl Values
//------------------------------------------------------------------------------------------------------
void assign_flightcontrol_values(serial_data_struct* pdata_package_assign){
fc_values.value_gas = pdata_package_assign->data[config_data.channel_gas*2];
fc_values.value_gier = pdata_package_assign->data[config_data.channel_gier*2];
fc_values.value_nick = pdata_package_assign->data[config_data.channel_nick*2];
fc_values.value_roll = pdata_package_assign->data[config_data.channel_roll*2];
fc_values.value_heightControl = pdata_package_assign->data[config_data.channel_heightControl*2];
fc_values.value_autostart = pdata_package_assign->data[config_data.channel_autostart*2];
fc_values.value_gps = pdata_package_assign->data[config_data.channel_gps*2];
fc_values.value_carefree = pdata_package_assign->data[(config_data.channel_carefree+1)*2];
fc_values.value_dynamicPositionHold = pdata_package_assign->data[config_data.dynamicPositionHold*2];
 
u8 *tmpData = (unsigned char *) &fc_values;
for (int i = 0; i < 9; ++i)
{
printf("%d \n", tmpData[i]);
}
}
 
//>> Assign 3D Data from NaviCtrl
//------------------------------------------------------------------------------------------------------
void assign_3d_data_NC(serial_data_struct* pdata_package_flight_data){
flight_data.StickNick = pdata_package_flight_data->data[6];
flight_data.StickRoll = pdata_package_flight_data->data[7];
flight_data.StickYaw = pdata_package_flight_data->data[8];
flight_data.StickGas = pdata_package_flight_data->data[9];
 
printf("%d\n", flight_data.StickGas);
}
 
//>> Assign 3D Data from FlightCtrl
//------------------------------------------------------------------------------------------------------
void assign_3d_data_FC(serial_data_struct* pdata_package_flight_data){
flight_data.AccZ = pdata_package_flight_data->data[7];
}
 
//>> Transmit Requests or Commands to the kopter
//------------------------------------------------------------------------------------------------------
serial_data_struct data_package_requests;
void request_to_kopter(u8 request){
switch(request)
{
case 1: //Get Configuration
data_package_requests.data[0] = 3; //Number of configuration-Set (Parametersatz);
data_package_requests.data[1] = 217;
data_package_requests.data[2] = 99;
create_serial_frame(1, 'q', 3, &data_package_requests);
transmit_data(TO_KOPTER, &data_package_requests);
memset(data_package_requests.txrxdata, 0, 1023);
memset(data_package_requests.data, 0, 1023);
break;
case 2: //Request Flightcontrol Values
create_serial_frame(1, 'p', 0, &data_package_requests);
transmit_data(TO_KOPTER, &data_package_requests);
memset(data_package_requests.txrxdata, 0, 1023);
memset(data_package_requests.data, 0, 1023);
break;
case 3:
data_package_requests.data[0] = 0;
data_package_requests.data[1] = 246;
data_package_requests.data[2] = 18;
create_serial_frame(0, 'a', 3, &data_package_requests);
transmit_data(TO_KOPTER, &data_package_requests);
memset(data_package_requests.txrxdata, 0, 1023);
memset(data_package_requests.data, 0, 1023);
break;
 
case 4: //Switch to flightcontrol
data_package_requests.data[0] = 0;
data_package_requests.data[1] = 236;
data_package_requests.data[2] = 91;
create_serial_frame(2, 'u', 3, &data_package_requests);
transmit_data(TO_KOPTER, &data_package_requests);
memset(data_package_requests.txrxdata, 0, 1023);
memset(data_package_requests.data, 0, 1023);
break;
case 5: //Request 3D Data
data_package_requests.data[0] = 1;
create_serial_frame(2, 'c', 1, &data_package_requests);
transmit_data(TO_KOPTER, &data_package_requests);
memset(data_package_requests.txrxdata, 0, 1023);
memset(data_package_requests.data, 0, 1023);
break;
case 6: //Request Analog Values (FlightControl)
data_package_requests.data[0] = 1;
create_serial_frame(1, 'd', 1, &data_package_requests);
transmit_data(TO_KOPTER, &data_package_requests);
memset(data_package_requests.txrxdata, 0, 1023);
memset(data_package_requests.data, 0, 1023);
break;
}
 
}
 
//>> Analyze the data package
//------------------------------------------------------------------------------------------------------
void analyze_data_package(serial_data_struct* pdata_package_analyze){
switch(pdata_package_analyze->collecting_data[1] - 'a')
{
case 2: //NaviCtrl
switch(pdata_package_analyze->collecting_data[2])
{
case 'A': //Get Sensor lables
collect_serial_frame(pdata_package_analyze);
if(pdata_package_analyze->data[0] > 15 && pdata_package_analyze->data[0] < 20){ //Address for Sensorlables
add_sensor_lables(pdata_package_analyze);
create_serial_frame(2, 'A', 18, pdata_package_analyze);
}
break;
case 'D': //Get Analog Values
collect_serial_frame(pdata_package_analyze);
add_sensor_data(pdata_package_analyze);
create_serial_frame(2, 'D', 66, pdata_package_analyze);
break;
case 'C': //Get 3D Data
collect_serial_frame(pdata_package_analyze);
assign_3d_data_NC(pdata_package_analyze);
break;
}
break;
case 1: //FlightCtrl
switch(pdata_package_analyze->collecting_data[2])
{
case 'A': //Get Sensor lables
collect_serial_frame(pdata_package_analyze);
if(pdata_package_analyze->data[0] > 15 && pdata_package_analyze->data[0] < 20){ //Address for Sensorlables
add_sensor_lables(pdata_package_analyze);
create_serial_frame(1, 'A', 18, pdata_package_analyze);
}
break;
case 'D': //Get Analog Values
collect_serial_frame(pdata_package_analyze);
add_sensor_data(pdata_package_analyze);
//create_serial_frame(1, 'D', 66, pdata_package_analyze);
break;
case 'Q': //Get Configuration
collect_serial_frame(pdata_package_analyze);
//pdata_package_analyze->cmdLength = 0; //Do not send Configuration back to the MikroKopter Tool, it gives an Error. It is only needed for this program
read_configuration(pdata_package_analyze);
break;
case 'P': //Get FlightCtrl Values
collect_serial_frame(pdata_package_analyze);
//pdata_package_analyze->cmdLength = 0;
assign_flightcontrol_values(pdata_package_analyze);
break;
case 'C': //Get 3D Data
collect_serial_frame(pdata_package_analyze);
assign_3d_data_FC(pdata_package_analyze);
break;
}
case 0:
switch(pdata_package_analyze->collecting_data[2])
{
case 'a':
collect_serial_frame(pdata_package_analyze);
break;
case 'h':
collect_serial_frame(pdata_package_analyze);
break;
}
 
}
memset(pdata_package_analyze->collecting_data, 0, 1023);
}
 
void processing_init(){
request_to_kopter(SWITCH_FLIGHTCONTROL);
}
/RaspberryPi/ExPlat/processing.h
0,0 → 1,63
#ifndef _PROCESSING_H
#define _PROCESSING_H
 
#define INITIATE 3
#define GET_CONFIGURATION 1
#define GET_FLIGHTCONTROL_VALUES 2
#define GET_3D_DATA 5
#define SWITCH_FLIGHTCONTROL 4
#define GET_ANALOG_DATA 6
 
extern void processing_init();
extern void analyze_data_package(serial_data_struct* pdata_package);
extern void get_distance();
extern void request_to_kopter(u8 request);
extern void process_flow_data(serial_data_struct* pdata_package_flow_process);
extern void process_gps_data(serial_data_struct* pdata_package_gps_process);
 
volatile int Distance;
 
struct str_optical_flow
{
u64 time_usec;
float flow_comp_m_x;
float flow_comp_m_y;
float ground_distance;
int16 flow_x;
int16 flow_y;
u8 sensor_id;
u8 quality;
float gyroz;
};
struct str_optical_flow optical_flow_values;
 
struct str_optical_flow_rad
{
u64 time_usec;
u32 integration_time_us;
float integrated_x;
float integrated_y;
float integrated_xgyro;
float integrated_ygyro;
float integrated_zgyro;
u32 time_delta_distance_us;
float distance;
int16 temperature;
u8 sensor_id;
u8 quality;
};
struct str_optical_flow_rad optical_flow_rad;
 
struct str_gps
{
float latitude;
u8 lat_orientation;
float longitude;
u8 long_orientation;
float utc;
float utc_date;
u8 valid;
};
struct str_gps gps_value_struct;
 
#endif //_PROCESSING_H
/RaspberryPi/ExPlat/timer.c
0,0 → 1,68
#include "main.h"
#include "timer.h"
 
 
struct timeval startTimeSec; //Set at every start
struct timeval travelTime;
struct timeval intermitTime;
u8 sec_handler;
u8 msec_handler;
u16 time_in_msec;
 
//>> Call for intervals in Seconds
//------------------------------------------------------------------------------------------------------
u8 interval_in_sec(u8 number_of_seconds){
if(sec_handler){
gettimeofday(&travelTime, NULL);
if(!((travelTime.tv_sec - startTimeSec.tv_sec) % number_of_seconds)){
return(1);
}else{return(0);}
}else{return(0);}
}
 
//>> Call for intervals in Milliseconds
//------------------------------------------------------------------------------------------------------
u8 interval_in_msec(u16 number_of_milliseconds){
if(msec_handler)
{
if(!(time_in_msec % number_of_milliseconds)){
return(1);
}else{return(0);}
}else{return(0);}
}
 
//>> Reset Timer for every loop cycle
//------------------------------------------------------------------------------------------------------
u16 msec_time_compare1;
u16 msec_time_compare2;
void reset_timer(){
gettimeofday(&intermitTime, NULL);
 
msec_time_compare1 = intermitTime.tv_usec/1000;
if(!(msec_time_compare1 == msec_time_compare2)){
time_in_msec++;
msec_handler = 1;
}else{
msec_handler = 0;
}
if(time_in_msec == 10001){
time_in_msec = 1;
}
msec_time_compare2 = intermitTime.tv_usec/1000;
 
if(!(intermitTime.tv_sec == travelTime.tv_sec)){
sec_handler = 1;
}else{
sec_handler = 0;
}
}
 
//>> Initialize Timer, store reference Time
//------------------------------------------------------------------------------------------------------
void timer_init(){
gettimeofday(&startTimeSec, NULL);
sec_handler = 1;
msec_handler = 1;
time_in_msec = 0;
 
}
/RaspberryPi/ExPlat/timer.h
0,0 → 1,10
#ifndef _TIMER_H
#define _TIMER_H
 
extern void timer_init();
extern void reset_timer();
extern u8 interval_in_sec(u8 number_of_seconds);
extern u8 interval_in_msec(u16 number_of_milliseconds);
 
 
#endif //_TIMER_H
/RaspberryPi/ExPlat/types.h
0,0 → 1,39
#ifndef _TYPES_H
#define _TYPES_H
 
typedef signed char int8;
typedef unsigned char u8;
typedef signed int int16;
typedef unsigned int u16;
typedef signed long int int32;
typedef unsigned long int u32;
typedef signed long long int int64;
typedef unsigned long long int u64;
 
#define TRUE 1
#define FALSE 0
 
//>> Main struct for Communication
//------------------------------------------------------------------------------------------------------
typedef struct
{
u8 c;
u8 collecting;
int count;
u8 address;
u8 cmdID;
u8 data[1024];
u8 collecting_data[1024];
u8 txrxdata[1024];
u16 position;
u16 dataLength;
u8 position_package;
u8 position_package_gps;
u16 cmdLength;
u8 readyForTransmit;
u8 length_payload;
u8 msg_id;
u8 gps_data[30][20];
}__attribute__((packed)) serial_data_struct;
 
#endif //_TYPES_H
/RaspberryPi/ExPlat/uart.c
0,0 → 1,429
#include "main.h"
#include "uart.h"
 
int uart0_computer = -1;
int uart1_kopter = -1;
int uart2_flow = -1;
int uart3_gps = -1;
 
//>> Storing Chars one by one
//------------------------------------------------------------------------------------------------------
u8 get_char(serial_data_struct* pdata_package){
if(pdata_package->count--)
{
pdata_package->c = pdata_package->txrxdata[pdata_package->position++];
return(1);
}else{return(0);}
}
 
//>> Searching for initiation-character and storing message
//------------------------------------------------------------------------------------------------------
u8 collect_data(serial_data_struct* pdata_package){
if(pdata_package->c == '#')
{
pdata_package->collecting = 1;
}
if(pdata_package->collecting)
{
pdata_package->collecting_data[pdata_package->position_package++] = pdata_package->c;
if(pdata_package->c == '\r'){
return(0);
}
}
return(1);
}
 
//>> Searching for initiation-character and storing message (for Flow Control)
//------------------------------------------------------------------------------------------------------
u8 collect_data_flow(serial_data_struct* pdata_package){
if(pdata_package->c == 254)
{
pdata_package->collecting = 1;
}
if(pdata_package->collecting)
{
pdata_package->collecting_data[pdata_package->position_package++] = pdata_package->c;
if(pdata_package->position_package == pdata_package->length_payload + 8){
return(0);
}
}
return(1);
}
 
//>> Searching for initiation-character and storing message (for GPS)
//------------------------------------------------------------------------------------------------------
u8 collect_data_gps(serial_data_struct* pdata_package){
if(pdata_package->c == '$')
{
pdata_package->collecting = 1;
}
if(pdata_package->collecting)
{
if(pdata_package->c == ','){
pdata_package->position_package_gps++;
pdata_package->position_package = 0;
}else{
pdata_package->gps_data[pdata_package->position_package_gps][pdata_package->position_package++] = pdata_package->c;
}
if(pdata_package->c == '\r'){
return(0);
}
}
return(1);
}
 
float tmpflow = 0.0;
//>> Receiving Data from the Optical Flow Module and processing it
//------------------------------------------------------------------------------------------------------
void receive_data_from_flow(serial_data_struct* pdata_package_flow){
if (uart2_flow != -1)
{
int rx_length = read(uart2_flow, (void*)pdata_package_flow->txrxdata, 1024);
if (rx_length > 0)
{
pdata_package_flow->cmdLength = rx_length;
 
pdata_package_flow->count = rx_length;
pdata_package_flow->position = 0;
while(get_char(pdata_package_flow))
{
if(!collect_data_flow(pdata_package_flow))
{
pdata_package_flow->collecting = 0;
pdata_package_flow->dataLength = pdata_package_flow->position_package;
pdata_package_flow->position_package = 0;
//|----------------------------Process Flow Data----------------------------|//
//| |//
process_flow_data(pdata_package_flow);
//perform_flight_correction();
//| |//
//|----------------------------Process Flow Data----------------------------|//
memset(pdata_package_flow->collecting_data, 0, 1023);
}else{
if(pdata_package_flow->position_package == 6){
pdata_package_flow->length_payload = pdata_package_flow->collecting_data[1];
pdata_package_flow->msg_id = pdata_package_flow->collecting_data[5];
}
if(pdata_package_flow->collecting_data[0] != 254){
memset(pdata_package_flow->collecting_data, 0, 1023);
memset(pdata_package_flow->txrxdata, 0, 1023);
pdata_package_flow->collecting = 0;
pdata_package_flow->position_package = 0;
pdata_package_flow->msg_id = 0;
}
}
}
memset(pdata_package_flow->txrxdata, 0, 1023);
}
}else{
printf("FLOW RX Error\n");
}
}
 
//>> Receiving Data from the MikroKopter-tool und transmitting it to the kopter
//------------------------------------------------------------------------------------------------------
void receive_data_from_computer(serial_data_struct* pdata_package_receive_computer, u8 psendThrough){
if (uart0_computer != -1)
{
memset(pdata_package_receive_computer->txrxdata, 0, 1023);
int rx_length = read(uart0_computer, (void*)pdata_package_receive_computer->txrxdata, 256); //Filestream, buffer to store in, number of bytes to read (max)
if (rx_length > 0)
{
pdata_package_receive_computer->cmdLength = rx_length;
transmit_data(TO_KOPTER, pdata_package_receive_computer);
 
if(!psendThrough){
pdata_package_receive_computer->count = rx_length;
pdata_package_receive_computer->position = 0;
while(get_char(pdata_package_receive_computer))
{
if(!collect_data(pdata_package_receive_computer))
{
pdata_package_receive_computer->collecting = 0;
pdata_package_receive_computer->dataLength = pdata_package_receive_computer->position_package;
pdata_package_receive_computer->position_package = 0;
u16 crc = 0;
u8 crc1, crc2;
for (int i = 0; i < pdata_package_receive_computer->dataLength - 3; i++)
{
crc += pdata_package_receive_computer->collecting_data[i];
}
crc %= 4096;
crc1 = '=' + crc / 64;
crc2 = '=' + crc % 64;
if(crc1 == pdata_package_receive_computer->collecting_data[pdata_package_receive_computer->dataLength - 3] && crc2 == pdata_package_receive_computer->collecting_data[pdata_package_receive_computer->dataLength - 2])
{
analyze_data_package(pdata_package_receive_computer);
//>> CRC OK
pdata_package_receive_computer->position_package = 0;
}else{
//>> CRC NOT OK
printf("RX Checksum Error\n");
pdata_package_receive_computer->position_package = 0;
memset(pdata_package_receive_computer->collecting_data, 0, 1023);
}
}
}
}
}
}else{
printf("RX Error\n");
}
}
 
//>> Receiving Data from the Kopter and collecting serial frame if needed
//------------------------------------------------------------------------------------------------------
void receive_data_from_kopter(serial_data_struct* pdata_package_receive_kopter){
if (uart1_kopter != -1)
{
memset(pdata_package_receive_kopter->txrxdata, 0, 1023);
int rx_length = read(uart1_kopter, (void*)pdata_package_receive_kopter->txrxdata, 256); //Filestream, buffer to store in, number of bytes to read (max)
if (rx_length > 0)
{
pdata_package_receive_kopter->cmdLength = rx_length;
pdata_package_receive_kopter->count = rx_length;
pdata_package_receive_kopter->position = 0;
while(get_char(pdata_package_receive_kopter))
{
if(!collect_data(pdata_package_receive_kopter))
{
pdata_package_receive_kopter->collecting = 0;
pdata_package_receive_kopter->dataLength = pdata_package_receive_kopter->position_package;
pdata_package_receive_kopter->position_package = 0;
u16 crc = 0;
u8 crc1, crc2;
for (int i = 0; i < pdata_package_receive_kopter->dataLength - 3; i++)
{
crc += pdata_package_receive_kopter->collecting_data[i];
}
crc %= 4096;
crc1 = '=' + crc / 64;
crc2 = '=' + crc % 64;
if(crc1 == pdata_package_receive_kopter->collecting_data[pdata_package_receive_kopter->dataLength - 3] && crc2 == pdata_package_receive_kopter->collecting_data[pdata_package_receive_kopter->dataLength - 2])
{
analyze_data_package(pdata_package_receive_kopter);
//>> CRC OK
pdata_package_receive_kopter->position_package = 0;
}else{
//>> CRC NOT OK
printf("RX Checksum Error\n");
pdata_package_receive_kopter->position_package = 0;
memset(pdata_package_receive_kopter->collecting_data, 0, 1023);
}
}
}
transmit_data(TO_COMPUTER, pdata_package_receive_kopter);
}
}else{
printf("KOPTER RX Error\n");
}
}
 
//>> Receiving Data from the Optical Flow Module and processing it
//------------------------------------------------------------------------------------------------------
void receive_data_from_gps(serial_data_struct* pdata_package_gps){
if (uart3_gps != -1)
{
int rx_length = read(uart3_gps, (void*)pdata_package_gps->txrxdata, 1024);
if (rx_length > 0)
{
pdata_package_gps->cmdLength = rx_length;
pdata_package_gps->count = rx_length;
pdata_package_gps->position = 0;
while(get_char(pdata_package_gps))
{
if(!collect_data_gps(pdata_package_gps))
{
pdata_package_gps->collecting = 0;
pdata_package_gps->dataLength = pdata_package_gps->position_package_gps;
pdata_package_gps->position_package = 0;
pdata_package_gps->position_package_gps = 0;
//|----------------------------Process Flow Data----------------------------|//
//|
for (int i = 0; i < pdata_package_gps->dataLength; ++i)
{
process_gps_data(pdata_package_gps);
pdata_package_gps->position_package++;
}
pdata_package_gps->position_package = 0;
//| |//
//|----------------------------Process Flow Data----------------------------|//
memset(pdata_package_gps->gps_data, 0, 30*20*sizeof(pdata_package_gps->gps_data[0][0]));
}
}
memset(pdata_package_gps->txrxdata, 0, 1023); }
}else{
printf("GPS RX Error\n");
}
}
 
 
//>> Transmitting data
//------------------------------------------------------------------------------------------------------
void transmit_data(int uart_filestream, serial_data_struct* pdata_package_transmit){
if (uart_filestream == 1)
{
uart_filestream = uart0_computer;
/*
printf("TO COMPUTER\n");
printf("%s\n", pdata_package_transmit->txrxdata);
*/
}else if(uart_filestream == 2)
{
uart_filestream = uart1_kopter;
/*
printf("TO KOPTER\n");
printf("%s\n", pdata_package_transmit->txrxdata);
for (int i = 0; i < pdata_package_transmit->cmdLength; ++i)
{
printf("%d ", pdata_package_transmit->txrxdata[i]);
}
printf("\n");
*/
}else if(uart_filestream == 3){
uart_filestream = uart2_flow;
}
if (uart_filestream != -1)
{
int count = write(uart_filestream, pdata_package_transmit->txrxdata, pdata_package_transmit->cmdLength);
if (count < 0)
{
//printf("UART TX error: %d\n", uart_filestream);
}
}
}
 
//>> Adding address and command ID, encoding and checksum
//------------------------------------------------------------------------------------------------------
void create_serial_frame(u8 address, u8 cmdID, u16 cmdLength, serial_data_struct* pdata_package_create){
pdata_package_create->txrxdata[0] = '\r';
pdata_package_create->txrxdata[1] = '#';
pdata_package_create->txrxdata[2] = address + 'a';
pdata_package_create->txrxdata[3] = cmdID;
//encode data
u8 a,b,c;
int counter = 0;
int u = 4;
while(cmdLength){
if(cmdLength)
{
cmdLength--;
a = pdata_package_create->data[counter++];
}else{a = 0; counter++;};
if(cmdLength)
{
cmdLength--;
b = pdata_package_create->data[counter++];
}else{b = 0; counter++;};
if(cmdLength)
{
cmdLength--;
c = pdata_package_create->data[counter++];
}else{c = 0; counter++;};
pdata_package_create->txrxdata[u++] = '=' + (a >> 2);
pdata_package_create->txrxdata[u++] = '=' + (((a & 0x03) << 4) | ((b & 0xf0) >> 4));
pdata_package_create->txrxdata[u++] = '=' + (((b & 0x0f) << 2) | ((c & 0xc0) >> 6));
pdata_package_create->txrxdata[u++] = '=' + (c & 0x3f);
}
//add Checksum
u16 crc = 0;
u8 crc1, crc2;
for (int i = 1; i < u; i++)
{
crc += pdata_package_create->txrxdata[i];
}
crc %= 4096;
crc1 = '=' + crc / 64;
crc2 = '=' + crc % 64;
pdata_package_create->txrxdata[u++] = crc1;
pdata_package_create->txrxdata[u++] = crc2;
pdata_package_create->txrxdata[u++] = '\r';
 
pdata_package_create->cmdLength = u;
}
 
//>> Decoding Data and retrieving address and cmdID
//------------------------------------------------------------------------------------------------------
void collect_serial_frame(serial_data_struct* pdata_package_collect){
pdata_package_collect->position_package++; //first character: #
pdata_package_collect->address = pdata_package_collect->collecting_data[pdata_package_collect->position_package++] - 'a'; //address
pdata_package_collect->cmdID = pdata_package_collect->collecting_data[pdata_package_collect->position_package++]; //cmdID
u8 a, b, c, d;
u16 datacpy = 0;
while(pdata_package_collect->position_package < pdata_package_collect->dataLength-3){
a = pdata_package_collect->collecting_data[pdata_package_collect->position_package++] - '=';
b = pdata_package_collect->collecting_data[pdata_package_collect->position_package++] - '=';
c = pdata_package_collect->collecting_data[pdata_package_collect->position_package++] - '=';
d = pdata_package_collect->collecting_data[pdata_package_collect->position_package++] - '=';
 
pdata_package_collect->data[datacpy++] = (a << 2) | (b >> 4);
pdata_package_collect->data[datacpy++] = ((b & 0x0f) << 4) | (c >> 2);
pdata_package_collect->data[datacpy++] = ((c & 0x03) << 6) | d;
}
pdata_package_collect->dataLength = datacpy;
pdata_package_collect->position_package = 0;
/*
printf("%s\n", pdata_package_collect->collecting_data);
for (int i = 0; i < datacpy; ++i)
{
printf("|%d|: %d ", i, pdata_package_collect->data[i]);
}
 
printf("%s\n", pdata_package_collect->data);
*/
}
 
 
//>> Initializing serial interface
//------------------------------------------------------------------------------------------------------
void uart_init(){
uart0_computer = open(SERIAL_COMPUTER, O_RDWR | O_NOCTTY | O_NDELAY);
uart1_kopter = open(SERIAL_KOPTER,O_RDWR | O_NOCTTY | O_NDELAY);
uart2_flow = open(SERIAL_FLOW,O_RDWR | O_NOCTTY | O_NDELAY);
uart3_gps = open(SERIAL_GPS,O_RDWR | O_NOCTTY | O_NDELAY);
if (uart0_computer == -1)
{
printf("Error - Unable to open UART0 (Computer)!\n");
}
if (uart1_kopter == -1)
{
printf("Error - Unable to open UART1 (Kopter)!\n");
}
if (uart2_flow == -1)
{
printf("Error - Unable to open UART2 (FLOW)!\n");
}
if (uart3_gps == -1)
{
printf("Error - Unable to open UART2 (GPS)!\n");
}
//UART Options
struct termios options;
tcgetattr(uart0_computer, &options);
options.c_cflag = B57600 | CS8 | CLOCAL | CREAD;
options.c_iflag = IGNPAR;
options.c_oflag = 0;
options.c_lflag = 0;
tcflush(uart0_computer, TCIFLUSH);
tcsetattr(uart0_computer, TCSANOW, &options);
tcflush(uart1_kopter, TCIFLUSH);
tcsetattr(uart1_kopter, TCSANOW, &options);
tcflush(uart2_flow, TCIFLUSH);
tcsetattr(uart2_flow, TCSANOW, &options);
//UART Options
struct termios options_flow;
tcgetattr(uart3_gps, &options_flow);
options_flow.c_cflag = B9600 | CS8 | CLOCAL | CREAD;
options.c_iflag = IGNPAR;
options_flow.c_oflag = 0;
options_flow.c_lflag = 0;
tcflush(uart3_gps, TCIFLUSH);
tcsetattr(uart3_gps, TCSANOW, &options_flow);
}
/RaspberryPi/ExPlat/uart.h
0,0 → 1,45
#ifndef _UART_H
#define _UART_H
 
//addresses
#define FC_address 1 //(b)
#define NC_address 2 //(c)
#define MK3MAG_address 3 //(d)
#define BL_CTRL_address 5 //(f)
 
//Command IDs
#define SERIAL_CHANNELS 'y'
#define EXTERNAL_CONTROL 'b'
 
//Serial Addresses
#define SERIAL_COMPUTER "/dev/ttyUSB0"
#define SERIAL_KOPTER "/dev/ttyUSB1"
#define SERIAL_FLOW "/dev/ttyACM0"
#define SERIAL_GPS "/dev/ttyAMA0"
#define ADDRESS 0x42
 
//Filestream
#define TO_KOPTER 2
#define TO_COMPUTER 1
#define TO_FLOW 3
 
//struct js_event e;
 
extern void create_serial_frame(u8 address, u8 cmdID, u16 cmdLength, serial_data_struct* pdata_package_create);
extern void collect_serial_frame(serial_data_struct* pdata_package_collect);
extern void receive_data_from_computer(serial_data_struct* pdata_package_receive_computer, u8 sendThrough);
extern void receive_data_from_kopter(serial_data_struct* pdata_package_receive_kopter);
extern void transmit_data(int uart_filestream, serial_data_struct* pdata_package_transmit);
 
extern void receive_data_from_flow(serial_data_struct* pdata_package_flow);
extern void receive_data_from_gps(serial_data_struct* pdata_package_gps);
extern void transmit_data_to_qt(serial_data_struct* pdata_package_transmit_flow);
extern void receive_data_from_qt(serial_data_struct* pdata_package_qt);
extern void transmit_data_to_flow(serial_data_struct* pdata_package_transmit_qt);
extern void i2c_init();
 
 
extern void uart_init();
 
 
#endif //_UART_H
/RaspberryPi/PiMoteCam/Makefile
0,0 → 1,23
OBJ = main.o calibration.o file.o frame.o gamepad.o gpio.o uart.o
DEPS = main.h calibration.h file.h frame.h gamepad.h gpio.h uart.h types.h
LIBS = -lncurses
CFLAGS = -std=c99 -Wall
CC = gcc
EXTENSION = .c
 
#define a rule that applies to all files ending in the .o suffix, which says that the .o file depends upon the .c version of the file and all the .h files included in the DEPS macro. Compile each object file
%.o: %$(EXTENSION) $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
 
#Combine them into the output file
#Set your desired exe output file name here
all: PiMote clean
 
PiMote: $(OBJ)
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
 
#Cleanup
.PHONY: clean
 
clean:
rm -f *.o *~ core *~
/RaspberryPi/PiMoteCam/PiMote
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/RaspberryPi/PiMoteCam/PiMote
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/RaspberryPi/PiMoteCam/calibration.c
0,0 → 1,122
#include "main.h"
#include "calibration.h"
#include "frame.h"
#include "file.h"
#include "gpio.h"
 
 
void calibrate(void){
frame_print("Please calibrate. Begin with Layout, assign buttons and axis:\n", 1, 0);
int i = 0;
while(i < NUMBER_OF_AXES_USED){
frame_print("\n (Axis) ", 0, 0);
frame_print(LablesOfAxis[i], 0, 0);
int u = -1;
int axisDefault = 0;
while(1){if(!value_sum(1)){break;}} //Wait until all buttons released
while(u == -1){
for (int p = 0; p < NumberOfAxesAvailiable; p++)
{
read_gamepad_data();
if(u == -1 && Axis[p] != axisDefault){u = p;}
}
}
GamepadLayout[i] = u;
i++;
frame_print(" check", 0, 0);
buzzer_short(1);
}
while(i < (NUMBER_OF_BUTTONS_USED + NUMBER_OF_AXES_USED)){
frame_print("\n (Button) ", 0, 0);
frame_print(LablesOfButtons[i - NUMBER_OF_AXES_USED], 0, 0);
int u = -1;
while(1){if(!value_sum(0)){break;}}
while(u == -1){
u = check_if_button_pushed();
}
GamepadLayout[i] = u;
i++;
frame_print(" check", 0, 0);
buzzer_short(1);
}
while(1){if(!value_sum(0)){break;}}
frame_print("Press Button 1 to continue...", 1, 1);
while(!check_if_button_pushed() == 0){};
buzzer_short(1);
frame_print("To calibrate the maximum value of the axis, \n pull and hold the assigned CamNick axis at the maximum \n and store the value by pressing any button.\n\n Maximum Value of Nick axis: ", 1, 0);
while(1){if(!value_sum(0)){break;}}
while(1){
read_gamepad_data();
if(value_sum(0))
{
MaxAxisValue = Axis[GamepadLayout[0]];
break;
}
}
buzzer_short(1);
fflush(stdout);
frame_print(" check", 0, 0);
write_file();
frame_print("", 1, 0);
}
 
//>> Ensuring that no button is being pushed and no axis moved
//------------------------------------------------------------------------------------------------------
int value_sum(int q){
read_gamepad_data();
int tmp = 0;
if(q)
{
for (int i = 0; i < NumberOfAxesAvailiable; ++i)
{
tmp += Axis[i];
}
}
if(!q)
{
for (int i = 0; i < NumberOfButtonsAvailiable; ++i)
{
tmp += Button[i];
}
}
return(tmp);
}
 
//>> Initializing calibration of Gamepad
//------------------------------------------------------------------------------------------------------
void calibration_init(){
if(FileExists){
frame_stay("Found Profile!\n\n Pad: (If connected)\n %s\n %d Axis\n %d Buttons", GamepadConnected, NUMBER_OF_AXES_USED, NUMBER_OF_BUTTONS_USED);
frame_print("Press Button 1 for recalibration .", 1, 1);
int i = 0;
buzzer_short(1);
while(i < 500){
if(check_if_button_pushed() == 0){
i = 1;
buzzer_short(3);
break;
}
usleep(5000);
if(!(i%100)){
frame_print(" .", 0, 1);
buzzer_short(1);
}
i++;
}
if(i == 1)
{
calibrate();
frame_print("START", 1, 1);
}else
{
while(1){if(!value_sum(0)){break;}
}
frame_print("START", 1, 1);
}
}else{
buzzer_short(5);
frame_stay("No Profile found!\n\n Pad connected:\n %s\n %d Axis\n %d Buttons", GamepadConnected, NUMBER_OF_AXES_USED, NUMBER_OF_BUTTONS_USED);
calibrate();
frame_print("START", 1, 1);
}
}
/RaspberryPi/PiMoteCam/calibration.h
0,0 → 1,7
#ifndef _CALIBRATION_H
#define _CALIBRATION_H
 
extern void calibration_init();
extern int value_sum(int q);
 
#endif //_CALIBRATION_H
/RaspberryPi/PiMoteCam/configf.txt
0,0 → 1,15
#Gamepad Configuration File
 
#layout
 
camNick: 2
camRoll: 3
camGier: 0
camZoom: 1
startRecord: 0
stopRecord: 1
trigger: 7
 
#Max value of axis
 
MaxAxisValue: -32767
/RaspberryPi/PiMoteCam/file.c
0,0 → 1,81
#include "main.h"
#include "file.h"
 
int MaxAxisValue;
u8 GamepadLayout[30];
u8 FileExists;
 
const char* LablesOfAxis[NUMBER_OF_AXES_USED] =
{
"camNick:", // GamepadLayout Position [0] Nick-Axis of Camera-Gimbal
"camRoll:", // GamepadLayout Position [1] Roll-Axis of Camera-Gimbal
"camGier:", // GamepadLayout Positoin [2] Yaw (Gier)-Axis of MikroKopter (for Camera Control)
"camZoom:", // GamepadLayout Position [3] Camera-Zoom
//"extNick:", // GamepadLayout Position [4] Nick-Axis of MikroKopter //Comment out for Cam Control only
//"extRoll:", // GamepadLayout Position [5] Roll-Axis of MikroKopter
//"extGier:", // GamepadLayout Position [6] Yaw(Gier)-Axis of MikroKopter
//"extGas:" // GamepadLayout Position [7] Gas of MikroKopter
};
const char* LablesOfButtons[NUMBER_OF_BUTTONS_USED] =
{
"startRecord:", // GamepadLayout Position [8] Start Recording Camcorder
"stopRecord:", // GamepadLayout Position [9] Stop Recording Camcorder
"trigger:", // GamepadLayout Position [10] Trigger a Camera
//"programOne:", // GamepadLayout Position [11] Program 1: Remote Control Camera //Comment out for Cam Control only
//"programTwo:", // GamepadLayout Position [12] Program 2: Remote Control MikroKopter
//"motorStart:", // GamepadLayout Position [13] Start Motors
//"motorStop:", // GamepadLayout Position [14] Stop Motors
//"sensPlus:", // GamepadLayout Position [15] Increase sensitivity of the controls
//"sensMinus:", // GamepadLayout Position [16] Decrease sensitivity of the controls
//"activate:" // GamepadLayout Position [17] Activate the controls
};
 
//>> Reading or creating configuration file
//------------------------------------------------------------------------------------------------------
int file_init(){
char line[50];
FILE *fp = fopen("/home/pi/PiMoteSwitch/configf.txt","r");
if(fp)
{
while( fgets(line,50,fp) ) {
for (int i = 0; i < NUMBER_OF_AXES_USED; i++)
{
if(strstr(line, LablesOfAxis[i]) != NULL){
char *token = strtok(line, " ");
token = strtok(NULL, " ");
GamepadLayout[i] = token[0] - '0';
}
}
for (int i = 0; i < NUMBER_OF_BUTTONS_USED; i++)
{
if(strstr(line, LablesOfButtons[i]) != NULL){
char *token = strtok(line, " ");
token = strtok(NULL, " ");
GamepadLayout[i + NUMBER_OF_AXES_USED] = token[0] - '0';
}
}
if(strstr(line, "MaxAxisValue") != NULL){
char *token = strtok(line, " ");
token = strtok(NULL, " ");
MaxAxisValue = strtol(token, (char **)NULL, 10);
}
memset(line, 0, 49);
}
fclose(fp);
return(1);
}
return(0);
}
 
//>> Write new configuration to file
//------------------------------------------------------------------------------------------------------
void write_file(void){
FILE *fp = fopen("/home/pi/PiMoteSwitch/configf.txt","w+");
fprintf(fp, "#Gamepad Configuration File\r\n\n");
fprintf(fp, "#layout\r\n\n");
for (int i = 0; i < NUMBER_OF_AXES_USED; i++){fprintf(fp, "%s %d\r\n", LablesOfAxis[i], GamepadLayout[i]);}
for (int i = 0; i < NUMBER_OF_BUTTONS_USED; i++){fprintf(fp, "%s %d\r\n", LablesOfButtons[i], GamepadLayout[i + NUMBER_OF_AXES_USED]);}
fprintf(fp, "\n#Max value of axis\r\n\nMaxAxisValue: ");
fprintf(fp, "%d", MaxAxisValue);
fclose(fp);
}
/RaspberryPi/PiMoteCam/file.h
0,0 → 1,18
#ifndef _FILE_H
#define _FILE_H
 
//#define NUMBER_OF_AXES_USED 8 //Comment out for Cam Control only
//#define NUMBER_OF_BUTTONS_USED 10 //Comment out for Cam Control only
 
#define NUMBER_OF_AXES_USED 4
#define NUMBER_OF_BUTTONS_USED 3
 
extern u8 GamepadLayout[30];
extern int MaxAxisValue;
extern const char* LablesOfAxis[NUMBER_OF_AXES_USED];
extern const char* LablesOfButtons[NUMBER_OF_BUTTONS_USED];
extern int file_init();
extern void write_file(void);
extern u8 FileExists;
 
#endif //_FILE_H
/RaspberryPi/PiMoteCam/frame.c
0,0 → 1,61
#include <curses.h>
#include "main.h"
#include "frame.h"
 
int main_y,main_x,sub_y,sub_x;
WINDOW *main_window;
WINDOW *stay_window;
WINDOW *sub_window;
 
void frame_print(const char *msg, int clear, int center){
if(clear){
wclear(sub_window);
if(center){
mvwprintw(sub_window,(main_y/4)-1,2,msg);
}else{
mvwprintw(sub_window,2,2,msg);
}
}else{
wprintw(sub_window, msg);
}
frame_refresh();
}
 
void frame_values(char *msg, int row, int line){
mvwprintw(sub_window,line,row,msg);
frame_refresh();
}
 
void frame_stay(char *msg, char* pad_frame, int axis_frame, int buttons_frame){
mvwprintw(stay_window,2,2,msg,pad_frame,axis_frame,buttons_frame);
wrefresh(stay_window);
frame_refresh();
}
 
void frame_refresh(){
box(sub_window,0,0);
wrefresh(sub_window);
}
 
void frame_init(){
initscr();
noecho();
curs_set(FALSE);
getmaxyx(stdscr,main_y,main_x);
sub_y = main_y/3;
sub_x = main_x/4;
main_window = newwin(main_y, main_x, 0, 0);
stay_window = newwin(main_y/4, main_x/8, main_y/16, main_x/2-main_x/16);
sub_window = newwin(main_y,main_x/2,sub_y,sub_x);
start_color();
init_pair(1, COLOR_RED, COLOR_WHITE);
wbkgd(main_window,COLOR_PAIR(1));
wbkgd(stay_window,COLOR_PAIR(1));
wbkgd(sub_window,COLOR_PAIR(1));
box(main_window,0,0);
box(sub_window,0,0);
mvwprintw(main_window,0,(main_x/2)-strlen(TITLE)/2,TITLE);
mvwprintw(main_window,main_y-1,(main_x/2)-strlen(COPY)/2,COPY);
wrefresh(main_window);
wrefresh(sub_window);
}
/RaspberryPi/PiMoteCam/frame.h
0,0 → 1,13
#ifndef _FRAME_H
#define _FRAME_H
 
#define TITLE "| MIKROKOPTER Camera Control |"
#define COPY "| (C)HiSystems |"
 
extern void frame_init();
extern void frame_print(const char *msg, int clear, int center);
extern void frame_values(char *msg, int row, int line);
extern void frame_stay(char *msg, char *pad_frame, int axis_frame, int buttons_frame);
extern void frame_refresh();
 
#endif //_FRAME_H
/RaspberryPi/PiMoteCam/gamepad.c
0,0 → 1,227
#include <linux/joystick.h>
#include "main.h"
#include "gamepad.h"
#include "frame.h"
 
volatile int *Axis = NULL;
volatile char *Button = NULL;
volatile float Sensitivity = 1.0;
int NumberOfAxesAvailiable;
int NumberOfButtonsAvailiable;
char GamepadConnected[30];
u8 IsActive = 0;
u8 ProgramSelect = 0;
 
int recordingButtonTemp = 125;
int padFd;
struct js_event js;
 
struct str_ExternControl externControl; //struct for controlling MikroKopter
struct str_ExternControl externControlGier; //struct for controlling Yaw (Gier) only
 
u8 gamepad_values_convert_for_cam(int tmpvalue){
u8 tmp;
double tmpdouble = tmpvalue;
tmp = ((((tmpdouble/(MaxAxisValue))-1)*125)-131)*-1;
if(tmp == 0){tmp = 255;}
return(tmp);
}
 
//>> Converting gamepad values to values readable by a MikroKopter
//------------------------------------------------------------------------------------------------------
u8 gamepad_values_convert_for_kopter(int tmpvalue){
u8 tmp;
double tmpdouble = tmpvalue;
tmp = ((((tmpdouble/(MaxAxisValue*Sensitivity))-1)*125)-131)*-1;
/*Increase values exponentially
if(tmpvalue < 0){
tmpdouble = tmpvalue*-1;
}else{tmpdouble = tmpvalue;}
tmp = ((30497*tmpdouble*tmpdouble*tmpdouble)/11187226521286200+(10667778*tmpdouble*tmpdouble)/532725072442200+(2592340312*tmpdouble)/11187226521286);
if(tmpvalue < 0){
tmp = (tmp*-1)+255;
}
*/
return(tmp);
}
 
u8 gamepad_values_convert_for_kopter_gas(int tmpvalue){
u8 tmp;
double tmpdouble = tmpvalue;
tmp = ((((tmpdouble/(MaxAxisValue))-1)*125)-131)*-1;
return(tmp);
}
 
int check_if_button_pushed(){
read_gamepad_data();
int buttonpushed = -1;
for (int i = 0; i < NumberOfButtonsAvailiable; i++)
{
if(Button[i] != 0){
buttonpushed = i;
}
}
return(buttonpushed);
}
 
//>> Check if controls are active
//------------------------------------------------------------------------------------------------------
void check_if_controls_active(){
if(check_if_button_pushed() == GamepadLayout[17] && IsActive == 0){
IsActive = 1;
while(1){if(!value_sum(0)){break;};}
}else if(check_if_button_pushed() == GamepadLayout[17] && IsActive == 1){
IsActive = 0;
while(1){if(!value_sum(0)){break;};}
}
}
//>> Check if program has been switched
//------------------------------------------------------------------------------------------------------
void check_program_switch(){
if(check_if_button_pushed() == GamepadLayout[11]){
frame_print("", 1, 0);
ProgramSelect = 1;
}else if(check_if_button_pushed() == GamepadLayout[12]){
frame_print("", 1, 0);
ProgramSelect = 2;
}
}
 
//>> Check if sensitivity of the controls has been adjusted
//------------------------------------------------------------------------------------------------------
void get_sensitivity(){
if(check_if_button_pushed() == GamepadLayout[15] && Sensitivity <= 2.0){
if(Sensitivity < 2){buzzer_short(1);}
Sensitivity += 0.2;
while(1){if(!value_sum(0)){break;};}
}else if(check_if_button_pushed() == GamepadLayout[16] && Sensitivity > 1.0){
if(Sensitivity > 1){buzzer_short(1);}
Sensitivity -= 0.2;
while(1){if(!value_sum(0)){break;};}
}
}
 
//>> Preparing Data for remotely controlling a Camera-Gimbal
//------------------------------------------------------------------------------------------------------
/*
void create_data_camera(serial_data_struct* pdata_package_camera_control, serial_data_struct* pdata_package_camera_control_gier){
pdata_package_camera_control->data[0] = gamepad_values_convert_for_cam(Axis[GamepadLayout[0]]); //Nick
pdata_package_camera_control->data[1] = gamepad_values_convert_for_cam(Axis[GamepadLayout[1]]); //Roll
pdata_package_camera_control->data[2] = gamepad_values_convert_for_cam(Axis[GamepadLayout[3]]); //
if(Button[GamepadLayout[8]] > 0){recordingButtonTemp = 131;}else if(Button[GamepadLayout[9]] > 0){recordingButtonTemp = 125;}
pdata_package_camera_control->data[3] = recordingButtonTemp;
if(Button[GamepadLayout[10]]){pdata_package_camera_control->data[4] = 131;}else{pdata_package_camera_control->data[4] = 125;}
int i = 5;
while(i < 12){
pdata_package_camera_control->data[i] = 0;
i++;
}
//Add Yaw (Gier)-funcionality
externControlGier.Gier = gamepad_values_convert_for_kopter(Axis[GamepadLayout[2]]);
externControlGier.Config = EC_VALID | EC_GAS_ADD;
externControlGier.Frame = 'z'; //character for echo
u8 *tmpData = (unsigned char *) &externControlGier;
for (int i = 0; i < pdata_package_camera_control_gier->cmdLength; ++i)
{
pdata_package_camera_control_gier->data[i] = tmpData[i];
}
 
//Print out values on screen
char tmpbuffer[255];
sprintf(tmpbuffer, "Nick: %d \n Roll: %d \n Gier: %d \n Zoom: %d \n Aufnahme: %d \n Auslösung: %d", pdata_package_camera_control->data[0], pdata_package_camera_control->data[1], pdata_package_camera_control_gier->data[2], pdata_package_camera_control->data[2], pdata_package_camera_control->data[3], pdata_package_camera_control->data[4]);
frame_values("VALUES", 5, 2);
frame_values(tmpbuffer, 5, 4);
}
*/
 
//>> Preparing Data for remotely controlling a Camera-Gimbal (CAM CONTROL ONLY)
//------------------------------------------------------------------------------------------------------
void create_data_camera(serial_data_struct* pdata_package_camera_control, serial_data_struct* pdata_package_camera_control_gier){
pdata_package_camera_control->data[0] = gamepad_values_convert_for_cam(Axis[GamepadLayout[0]]); //Nick
pdata_package_camera_control->data[1] = gamepad_values_convert_for_cam(Axis[GamepadLayout[1]]); //Roll
pdata_package_camera_control->data[2] = gamepad_values_convert_for_cam(Axis[GamepadLayout[3]]); //
if(Button[GamepadLayout[4]] > 0){recordingButtonTemp = 131;}else if(Button[GamepadLayout[5]] > 0){recordingButtonTemp = 125;}
pdata_package_camera_control->data[3] = recordingButtonTemp;
if(Button[GamepadLayout[6]]){pdata_package_camera_control->data[4] = 131;}else{pdata_package_camera_control->data[4] = 125;}
int i = 5;
while(i < 12){
pdata_package_camera_control->data[i] = 0;
i++;
}
//Add Yaw (Gier)-funcionality
externControlGier.Gier = gamepad_values_convert_for_kopter(Axis[GamepadLayout[2]]);
externControlGier.Config = EC_VALID | EC_GAS_ADD;
externControlGier.Frame = 'z'; //character for echo
u8 *tmpData = (unsigned char *) &externControlGier;
for (int i = 0; i < pdata_package_camera_control_gier->cmdLength; ++i)
{
pdata_package_camera_control_gier->data[i] = tmpData[i];
}
 
//Print out values on screen
char tmpbuffer[255];
sprintf(tmpbuffer, "Nick: %d \n Roll: %d \n Gier: %d \n Zoom: %d \n Aufnahme: %d \n Auslösung: %d", pdata_package_camera_control->data[0], pdata_package_camera_control->data[1], pdata_package_camera_control_gier->data[2], pdata_package_camera_control->data[2], pdata_package_camera_control->data[3], pdata_package_camera_control->data[4]);
frame_values("VALUES", 5, 2);
frame_values(tmpbuffer, 5, 4);
}
 
//>> Preparing Data for remotely controlling a MikroKopter
//------------------------------------------------------------------------------------------------------
void create_data_kopter(serial_data_struct* pdata_package_kopter_control){
if(check_if_button_pushed() == GamepadLayout[13]){ //Motor start
externControl.Nick = 131;
externControl.Roll = 131;
externControl.Gier = 131;
externControl.Gas = 131;
}else if(check_if_button_pushed() == GamepadLayout[14]){ //Motor stop
externControl.Nick = 131;
externControl.Roll = 125;
externControl.Gier = 125;
externControl.Gas = 131;
}else{
externControl.Nick = gamepad_values_convert_for_kopter(Axis[GamepadLayout[4]]);
externControl.Roll = gamepad_values_convert_for_kopter(Axis[GamepadLayout[5]]);
externControl.Gier = gamepad_values_convert_for_kopter(Axis[GamepadLayout[6]]);
externControl.Gas = gamepad_values_convert_for_kopter_gas(Axis[GamepadLayout[7]]);
}
externControl.Config = EC_VALID | EC_GAS_ADD | EC_IGNORE_RC;
externControl.Frame = 'z'; //character for echo
u8 *tmpData = (unsigned char *) &externControl;
for (int i = 0; i < pdata_package_kopter_control->cmdLength; ++i)
{
pdata_package_kopter_control->data[i] = tmpData[i];
}
//Print out values on screen
char tmpbuffer[255];
sprintf(tmpbuffer, "Nick: %d \n Roll: %d \n Gier: %d \n Gas : %d \n", pdata_package_kopter_control->data[0], pdata_package_kopter_control->data[1], pdata_package_kopter_control->data[2], pdata_package_kopter_control->data[3]);
frame_values("VALUES", 5, 2);
frame_values(tmpbuffer, 5, 4);
}
 
void read_gamepad_data(){
read(padFd, &js, sizeof(struct js_event));
switch (js.type & ~JS_EVENT_INIT)
{
case JS_EVENT_AXIS:
Axis [ js.number ] = js.value;
break;
case JS_EVENT_BUTTON:
Button [ js.number ] = js.value;
break;
}
}
 
//>> Initialize Gamepad
//------------------------------------------------------------------------------------------------------
void gamepad_init(){
if((padFd = open(GAME_PAD, O_RDONLY)) == -1)
{
printf( "Couldn't open gamepad\n" );
}
ioctl( padFd, JSIOCGAXES, &NumberOfAxesAvailiable );
ioctl( padFd, JSIOCGBUTTONS, &NumberOfButtonsAvailiable );
ioctl( padFd, JSIOCGNAME(80), &GamepadConnected );
Axis = (int *) calloc( NumberOfAxesAvailiable, sizeof( int ) );
Button = (char *) calloc( NumberOfButtonsAvailiable, sizeof( char ) );
fcntl( padFd, F_SETFL, O_NONBLOCK ); /* use non-blocking mode */
}
/RaspberryPi/PiMoteCam/gamepad.h
0,0 → 1,29
#ifndef _GAMEPAD_H
#define _GAMEPAD_H
 
#define GAME_PAD "/dev/input/js0"
 
//Defines for external control
#define EC_VALID 0x01 // only valid if this is 1
#define EC_GAS_ADD 0x02 // if 1 -> use the GAS Value not as MAX
#define EC_IGNORE_RC 0x80 // if 1 -> for Flying without RC-Control
 
extern void gamepad_init();
extern void read_gamepad_data();
extern void create_data_camera(serial_data_struct* pdata_package_camera_control, serial_data_struct* pdata_package_camera_control_gier);
extern void create_data_kopter(serial_data_struct* pdata_package_kopter_control);
extern int check_if_button_pushed();
extern void check_if_controls_active();
extern void check_program_switch();
extern void get_sensitivity();
 
extern volatile int *Axis;
extern volatile char *Button;
extern volatile float Sensitivity;
extern int NumberOfAxesAvailiable;
extern int NumberOfButtonsAvailiable;
extern char GamepadConnected[30];
extern u8 IsActive;
extern u8 ProgramSelect;
 
#endif //_GAMEPAD_H
/RaspberryPi/PiMoteCam/gpio.c
0,0 → 1,59
#include "main.h"
#include "gpio.h"
 
// IO Acces
struct bcm2835_peripheral {
unsigned long addr_p;
int mem_fd;
void *map;
volatile unsigned int *addr;
};
struct bcm2835_peripheral gpio = {GPIO_BASE};
 
 
int map_peripheral(struct bcm2835_peripheral *p)
{
// Open /dev/mem
if ((p->mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
printf("Failed to open /dev/mem, try checking permissions.\n");
return -1;
}
p->map = mmap(
NULL,
BLOCK_SIZE,
PROT_READ|PROT_WRITE,
MAP_SHARED,
p->mem_fd, // File descriptor to physical memory virtual file '/dev/mem'
p->addr_p // address in physical map that we want this memory block to expose
);
if (p->map == MAP_FAILED) {
perror("mmap");
return -1;
}
p->addr = (volatile unsigned int *)p->map;
return 0;
}
void unmap_peripheral(struct bcm2835_peripheral *p) {
munmap(p->map, BLOCK_SIZE);
close(p->mem_fd);
}
 
void buzzer_short(int seq){
INP_GPIO(4);
OUT_GPIO(4);
for (int i = 0; i < seq; ++i)
{
if(seq > 1){usleep(50000);}
GPIO_SET = 1 << 4;
usleep(50000);
GPIO_CLR = 1 << 4;
}
}
 
void gpio_init(){
if(map_peripheral(&gpio) == -1)
{
printf("Failed to map the physical GPIO registers into the virtual memory space.\n");
}
}
/RaspberryPi/PiMoteCam/gpio.h
0,0 → 1,22
#ifndef _GPIO_H
#define _GPIO_H
 
#define BCM2708_PERI_BASE 0x20000000
#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) // GPIO controller
#define BLOCK_SIZE (4*1024)
 
extern struct bcm2835_peripheral gpio;
 
// GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x)
#define INP_GPIO(g) *(gpio.addr + ((g)/10)) &= ~(7<<(((g)%10)*3))
#define OUT_GPIO(g) *(gpio.addr + ((g)/10)) |= (1<<(((g)%10)*3))
#define SET_GPIO_ALT(g,a) *(gpio.addr + (((g)/10))) |= (((a)<=3?(a) + 4:(a)==4?3:2)<<(((g)%10)*3))
#define GPIO_SET *(gpio.addr + 7) // sets bits which are 1 ignores bits which are 0
#define GPIO_CLR *(gpio.addr + 10) // clears bits which are 1 ignores bits which are 0
#define GPIO_READ(g) *(gpio.addr + 13) &= (1<<(g))
 
// Exposes the physical address defined in the passed structure using mmap on /dev/mem
extern void gpio_init();
extern void buzzer_short(int seq);
 
#endif //_GPIO_H
/RaspberryPi/PiMoteCam/main.c
0,0 → 1,43
#include "main.h"
 
 
u8 FileExists;
serial_data_struct data_package_camera_control; //Data Package for controlling the Camera
serial_data_struct data_package_camera_control_gier; //Data Package for controlling the Gier-Axis of the MikroKopter
serial_data_struct data_package_kopter_control; //Data Package for controlling the MikroKopter
 
int main(void){
frame_init();
FileExists = file_init();
gamepad_init();
gpio_init();
calibration_init();
uart_init();
buzzer_short(3);
for (;;)
{
//check_program_switch(); //Comment out for Cam Control only
//if(ProgramSelect == 1){
read_gamepad_data();
create_data_camera(&data_package_camera_control, &data_package_camera_control_gier);
create_serial_frame(1, 'y', 12, &data_package_camera_control); //address, Command ID, Serial Command Length, data
create_serial_frame(1, 'b', sizeof(struct str_ExternControl), &data_package_camera_control_gier); //Gier
transmit_data(&data_package_camera_control);
transmit_data(&data_package_camera_control_gier);
//}
/*
if(ProgramSelect == 2){
check_if_controls_active();
if(IsActive){
get_sensitivity();
read_gamepad_data();
create_data_kopter(&data_package_kopter_control);
create_serial_frame(1, 'b', sizeof(struct str_ExternControl), &data_package_kopter_control);
transmit_data(&data_package_kopter_control);
}
}
*/
usleep(5000); //200hz
}
}
/RaspberryPi/PiMoteCam/main.h
0,0 → 1,26
#ifndef _MAIN_H
#define _MAIN_H
 
#include <curses.h>
#include <stdio.h>
#include <string.h>
#include <termios.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/joystick.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "frame.h"
#include "types.h"
#include "file.h"
#include "uart.h"
#include "gamepad.h"
#include "calibration.h"
#include "gpio.h"
 
extern void usleep(int);
 
#endif //_MAIN_H
/RaspberryPi/PiMoteCam/types.h
0,0 → 1,40
#ifndef _TYPES_H
#define _TYPES_H
 
typedef unsigned char u8;
typedef unsigned short u16;
 
typedef struct
{
u8 address;
u8 cmdID;
u8 data[1024];
u8 txrxdata[1024];
u8 collecting;
u8 position_package;
u16 cmdLength;
 
}__attribute__((packed)) serial_data_struct;
 
 
typedef struct
{
u8 c;
u8 data[1024];
u16 position_rx;
u16 count;
}__attribute__((packed)) data_rx_st;
 
 
struct str_ExternControl
{
signed char Nick;
signed char Roll;
signed char Gier;
signed char Gas;
unsigned char Frame; // will return a confirm frame with this value
unsigned char Config;
unsigned char free;
};
 
#endif //_TYPES_H
/RaspberryPi/PiMoteCam/uart.c
0,0 → 1,91
#include "main.h"
#include "uart.h"
 
int uart0_filestream = -1;
int usb_stream = -1;
int data_length; //length of transmitting data string
 
 
//>> Adding checksum and transmitting data
//------------------------------------------------------------------------------------------------------
void transmit_data(serial_data_struct* pdata_package){
if (uart0_filestream != -1)
{
int count = write(uart0_filestream, pdata_package->txrxdata, pdata_package->cmdLength);
if (count < 0)
{
printf("UART TX error\n");
}
}
}
 
//>> Adding address and command ID, encoding and checksum
//------------------------------------------------------------------------------------------------------
void create_serial_frame(u8 address, u8 cmdID, u16 cmdLength, serial_data_struct* pdata_package){
pdata_package->txrxdata[0] = '#';
pdata_package->txrxdata[1] = address + 'a';
pdata_package->txrxdata[2] = cmdID;
 
//encode data
u8 a,b,c;
int counter = 0;
int u = 3;
while(cmdLength){
if(cmdLength)
{
cmdLength--;
a = pdata_package->data[counter++];
}else{a = 0; counter++;};
if(cmdLength)
{
cmdLength--;
b = pdata_package->data[counter++];
}else{b = 0; counter++;};
if(cmdLength)
{
cmdLength--;
c = pdata_package->data[counter++];
}else{c = 0; counter++;};
pdata_package->txrxdata[u++] = '=' + (a >> 2);
pdata_package->txrxdata[u++] = '=' + (((a & 0x03) << 4) | ((b & 0xf0) >> 4));
pdata_package->txrxdata[u++] = '=' + (((b & 0x0f) << 2) | ((c & 0xc0) >> 6));
pdata_package->txrxdata[u++] = '=' + (c & 0x3f);
}
 
//add Checksum
u16 crc = 0;
u8 crc1, crc2;
for (int i = 0; i < u; i++)
{
crc += pdata_package->txrxdata[i];
}
crc %= 4096;
crc1 = '=' + crc / 64;
crc2 = '=' + crc % 64;
pdata_package->txrxdata[u++] = crc1;
pdata_package->txrxdata[u++] = crc2;
pdata_package->txrxdata[u++] = '\r';
 
pdata_package->cmdLength = u;
}
 
 
//>> Initializing serial interface
//------------------------------------------------------------------------------------------------------
void uart_init(){
uart0_filestream = open(SERIAL, O_RDWR | O_NOCTTY | O_NDELAY);
if (uart0_filestream == -1)
{
printf("Error - Unable to open UART. Ensure it is not in use by another application\n");
}
//UART Options
struct termios options;
tcgetattr(uart0_filestream, &options);
options.c_cflag = B57600 | CS8 | CLOCAL | CREAD;
options.c_iflag = IGNPAR;
options.c_oflag = 0;
options.c_lflag = 0;
tcflush(uart0_filestream, TCIFLUSH);
tcsetattr(uart0_filestream, TCSANOW, &options);
//UART Options
}
/RaspberryPi/PiMoteCam/uart.h
0,0 → 1,24
#ifndef _UART_H
#define _UART_H
 
//addresses
#define FC_address 1 //(b)
#define NC_address 2 //(c)
#define MK3MAG_address 3 //(d)
#define BL_CTRL_address 5 //(f)
 
//Command IDs
#define SERIAL_CHANNELS 'y'
#define EXTERNAL_CONTROL 'b'
 
 
#define SERIAL "/dev/ttyAMA0"
 
//struct js_event e;
 
extern void create_serial_frame(u8 address, u8 cmdID, u16 cmdLength, serial_data_struct* pdata_package);
extern void transmit_data(serial_data_struct* pdata_package);
extern void encode_data(serial_data_struct* pdata_package);
extern void uart_init();
 
#endif //_UART_H
/RaspberryPi/PiMoteSwitch/Makefile
0,0 → 1,23
OBJ = main.o calibration.o file.o frame.o gamepad.o gpio.o uart.o
DEPS = main.h calibration.h file.h frame.h gamepad.h gpio.h uart.h types.h
LIBS = -lncurses
CFLAGS = -std=c99 -Wall
CC = gcc
EXTENSION = .c
 
#define a rule that applies to all files ending in the .o suffix, which says that the .o file depends upon the .c version of the file and all the .h files included in the DEPS macro. Compile each object file
%.o: %$(EXTENSION) $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
 
#Combine them into the output file
#Set your desired exe output file name here
all: PiMote clean
 
PiMote: $(OBJ)
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
 
#Cleanup
.PHONY: clean
 
clean:
rm -f *.o *~ core *~
/RaspberryPi/PiMoteSwitch/PiMote
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/RaspberryPi/PiMoteSwitch/PiMote
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/RaspberryPi/PiMoteSwitch/calibration.c
0,0 → 1,122
#include "main.h"
#include "calibration.h"
#include "frame.h"
#include "file.h"
#include "gpio.h"
 
 
void calibrate(void){
frame_print("Please calibrate. Begin with Layout, assign buttons and axis:\n", 1, 0);
int i = 0;
while(i < NUMBER_OF_AXES_USED){
frame_print("\n (Axis) ", 0, 0);
frame_print(LablesOfAxis[i], 0, 0);
int u = -1;
int axisDefault = 0;
while(1){if(!value_sum(1)){break;}} //Wait until all buttons released
while(u == -1){
for (int p = 0; p < NumberOfAxesAvailiable; p++)
{
read_gamepad_data();
if(u == -1 && Axis[p] != axisDefault){u = p;}
}
}
GamepadLayout[i] = u;
i++;
frame_print(" check", 0, 0);
buzzer_short(1);
}
while(i < (NUMBER_OF_BUTTONS_USED + NUMBER_OF_AXES_USED)){
frame_print("\n (Button) ", 0, 0);
frame_print(LablesOfButtons[i - NUMBER_OF_AXES_USED], 0, 0);
int u = -1;
while(1){if(!value_sum(0)){break;}}
while(u == -1){
u = check_if_button_pushed();
}
GamepadLayout[i] = u;
i++;
frame_print(" check", 0, 0);
buzzer_short(1);
}
while(1){if(!value_sum(0)){break;}}
frame_print("Press Button 1 to continue...", 1, 1);
while(!check_if_button_pushed() == 0){};
buzzer_short(1);
frame_print("To calibrate the maximum value of the axis, \n pull and hold the assigned CamNick axis at the maximum \n and store the value by pressing any button.\n\n Maximum Value of Nick axis: ", 1, 0);
while(1){if(!value_sum(0)){break;}}
while(1){
read_gamepad_data();
if(value_sum(0))
{
MaxAxisValue = Axis[GamepadLayout[0]];
break;
}
}
buzzer_short(1);
fflush(stdout);
frame_print(" check", 0, 0);
write_file();
frame_print("", 1, 0);
}
 
//>> Ensuring that no button is being pushed and no axis moved
//------------------------------------------------------------------------------------------------------
int value_sum(int q){
read_gamepad_data();
int tmp = 0;
if(q)
{
for (int i = 0; i < NumberOfAxesAvailiable; ++i)
{
tmp += Axis[i];
}
}
if(!q)
{
for (int i = 0; i < NumberOfButtonsAvailiable; ++i)
{
tmp += Button[i];
}
}
return(tmp);
}
 
//>> Initializing calibration of Gamepad
//------------------------------------------------------------------------------------------------------
void calibration_init(){
if(FileExists){
frame_stay("Found Profile!\n\n Pad connected:\n %s\n %d Axis\n %d Buttons", GamepadConnected, NUMBER_OF_AXES_USED, NUMBER_OF_BUTTONS_USED);
frame_print("Press Button 1 for recalibration .", 1, 1);
int i = 0;
buzzer_short(1);
while(i < 1000){
if(check_if_button_pushed() == 0){
i = 1;
buzzer_short(3);
break;
}
usleep(5000);
if(!(i%100)){
frame_print(" .", 0, 1);
buzzer_short(1);
}
i++;
}
if(i == 1)
{
calibrate();
frame_print("START", 1, 1);
}else
{
while(1){if(!value_sum(0)){break;}
}
frame_print("START", 1, 1);
}
}else{
buzzer_short(5);
frame_stay("No Profile found!\n\n Pad connected:\n %s\n %d Axis\n %d Buttons", GamepadConnected, NUMBER_OF_AXES_USED, NUMBER_OF_BUTTONS_USED);
calibrate();
frame_print("START", 1, 1);
}
}
/RaspberryPi/PiMoteSwitch/calibration.h
0,0 → 1,7
#ifndef _CALIBRATION_H
#define _CALIBRATION_H
 
extern void calibration_init();
extern int value_sum(int q);
 
#endif //_CALIBRATION_H
/RaspberryPi/PiMoteSwitch/configf.txt
0,0 → 1,26
#Gamepad Configuration File
 
#layout
 
camNick: 3
camRoll: 2
camGier: 0
camZoom: 1
extNick: 3
extRoll: 2
extGier: 0
extGas: 1
startRecord: 0
stopRecord: 3
trigger: 7
programOne: 4
programTwo: 5
motorStart: 9
motorStop: 8
sensPlus: 7
sensMinus: 6
activate: 2
 
#Max value of axis
 
MaxAxisValue: 32767
/RaspberryPi/PiMoteSwitch/file.c
0,0 → 1,81
#include "main.h"
#include "file.h"
 
int MaxAxisValue;
u8 GamepadLayout[30];
u8 FileExists;
 
const char* LablesOfAxis[NUMBER_OF_AXES_USED] =
{
"camNick:", // GamepadLayout Position [0] Nick-Axis of Camera-Gimbal
"camRoll:", // GamepadLayout Position [1] Roll-Axis of Camera-Gimbal
"camGier:", // GamepadLayout Positoin [2] Yaw (Gier)-Axis of MikroKopter (for Camera Control)
"camZoom:", // GamepadLayout Position [3] Camera-Zoom
"extNick:", // GamepadLayout Position [4] Nick-Axis of MikroKopter
"extRoll:", // GamepadLayout Position [5] Roll-Axis of MikroKopter
"extGier:", // GamepadLayout Position [6] Yaw(Gier)-Axis of MikroKopter
"extGas:" // GamepadLayout Position [7] Gas of MikroKopter
};
const char* LablesOfButtons[NUMBER_OF_BUTTONS_USED] =
{
"startRecord:", // GamepadLayout Position [8] Start Recording Camcorder
"stopRecord:", // GamepadLayout Position [9] Stop Recording Camcorder
"trigger:", // GamepadLayout Position [10] Trigger a Camera
"programOne:", // GamepadLayout Position [11] Program 1: Remote Control Camera
"programTwo:", // GamepadLayout Position [12] Program 2: Remote Control MikroKopter
"motorStart:", // GamepadLayout Position [13] Start Motors
"motorStop:", // GamepadLayout Position [14] Stop Motors
"sensPlus:", // GamepadLayout Position [15] Increase sensitivity of the controls
"sensMinus:", // GamepadLayout Position [16] Decrease sensitivity of the controls
"activate:" // GamepadLayout Position [17] Activate the controls
};
 
//>> Reading or creating configuration file
//------------------------------------------------------------------------------------------------------
int file_init(){
char line[50];
FILE *fp = fopen("/home/pi/PiMoteSwitch/configf.txt","r");
if(fp)
{
while( fgets(line,50,fp) ) {
for (int i = 0; i < NUMBER_OF_AXES_USED; i++)
{
if(strstr(line, LablesOfAxis[i]) != NULL){
char *token = strtok(line, " ");
token = strtok(NULL, " ");
GamepadLayout[i] = token[0] - '0';
}
}
for (int i = 0; i < NUMBER_OF_BUTTONS_USED; i++)
{
if(strstr(line, LablesOfButtons[i]) != NULL){
char *token = strtok(line, " ");
token = strtok(NULL, " ");
GamepadLayout[i + NUMBER_OF_AXES_USED] = token[0] - '0';
}
}
if(strstr(line, "MaxAxisValue") != NULL){
char *token = strtok(line, " ");
token = strtok(NULL, " ");
MaxAxisValue = strtol(token, (char **)NULL, 10);
}
memset(line, 0, 49);
}
fclose(fp);
return(1);
}
return(0);
}
 
//>> Write new configuration to file
//------------------------------------------------------------------------------------------------------
void write_file(void){
FILE *fp = fopen("/home/pi/PiMoteSwitch/configf.txt","w+");
fprintf(fp, "#Gamepad Configuration File\r\n\n");
fprintf(fp, "#layout\r\n\n");
for (int i = 0; i < NUMBER_OF_AXES_USED; i++){fprintf(fp, "%s %d\r\n", LablesOfAxis[i], GamepadLayout[i]);}
for (int i = 0; i < NUMBER_OF_BUTTONS_USED; i++){fprintf(fp, "%s %d\r\n", LablesOfButtons[i], GamepadLayout[i + NUMBER_OF_AXES_USED]);}
fprintf(fp, "\n#Max value of axis\r\n\nMaxAxisValue: ");
fprintf(fp, "%d", MaxAxisValue);
fclose(fp);
}
/RaspberryPi/PiMoteSwitch/file.h
0,0 → 1,15
#ifndef _FILE_H
#define _FILE_H
 
#define NUMBER_OF_AXES_USED 8
#define NUMBER_OF_BUTTONS_USED 10
 
extern u8 GamepadLayout[30];
extern int MaxAxisValue;
extern const char* LablesOfAxis[NUMBER_OF_AXES_USED];
extern const char* LablesOfButtons[NUMBER_OF_BUTTONS_USED];
extern int file_init();
extern void write_file(void);
extern u8 FileExists;
 
#endif //_FILE_H
/RaspberryPi/PiMoteSwitch/frame.c
0,0 → 1,61
#include <curses.h>
#include "main.h"
#include "frame.h"
 
int main_y,main_x,sub_y,sub_x;
WINDOW *main_window;
WINDOW *stay_window;
WINDOW *sub_window;
 
void frame_print(const char *msg, int clear, int center){
if(clear){
wclear(sub_window);
if(center){
mvwprintw(sub_window,(main_y/4)-1,2,msg);
}else{
mvwprintw(sub_window,2,2,msg);
}
}else{
wprintw(sub_window, msg);
}
frame_refresh();
}
 
void frame_values(char *msg, int row, int line){
mvwprintw(sub_window,line,row,msg);
frame_refresh();
}
 
void frame_stay(char *msg, char* pad_frame, int axis_frame, int buttons_frame){
mvwprintw(stay_window,2,2,msg,pad_frame,axis_frame,buttons_frame);
wrefresh(stay_window);
frame_refresh();
}
 
void frame_refresh(){
box(sub_window,0,0);
wrefresh(sub_window);
}
 
void frame_init(){
initscr();
noecho();
curs_set(FALSE);
getmaxyx(stdscr,main_y,main_x);
sub_y = main_y/3;
sub_x = main_x/4;
main_window = newwin(main_y, main_x, 0, 0);
stay_window = newwin(main_y/4, main_x/8, main_y/16, main_x/2-main_x/16);
sub_window = newwin(main_y,main_x/2,sub_y,sub_x);
start_color();
init_pair(1, COLOR_RED, COLOR_WHITE);
wbkgd(main_window,COLOR_PAIR(1));
wbkgd(stay_window,COLOR_PAIR(1));
wbkgd(sub_window,COLOR_PAIR(1));
box(main_window,0,0);
box(sub_window,0,0);
mvwprintw(main_window,0,(main_x/2)-strlen(TITLE)/2,TITLE);
mvwprintw(main_window,main_y-1,(main_x/2)-strlen(COPY)/2,COPY);
wrefresh(main_window);
wrefresh(sub_window);
}
/RaspberryPi/PiMoteSwitch/frame.h
0,0 → 1,13
#ifndef _FRAME_H
#define _FRAME_H
 
#define TITLE "| MIKROKOPTER Camera Control |"
#define COPY "| (C)HiSystems |"
 
extern void frame_init();
extern void frame_print(const char *msg, int clear, int center);
extern void frame_values(char *msg, int row, int line);
extern void frame_stay(char *msg, char *pad_frame, int axis_frame, int buttons_frame);
extern void frame_refresh();
 
#endif //_FRAME_H
/RaspberryPi/PiMoteSwitch/gamepad.c
0,0 → 1,194
#include <linux/joystick.h>
#include "main.h"
#include "gamepad.h"
#include "frame.h"
 
volatile int *Axis = NULL;
volatile char *Button = NULL;
volatile float Sensitivity = 1.0;
int NumberOfAxesAvailiable;
int NumberOfButtonsAvailiable;
char GamepadConnected[30];
u8 IsActive = 0;
u8 ProgramSelect = 0;
 
int recordingButtonTemp = 125;
int padFd;
struct js_event js;
 
struct str_ExternControl externControl; //struct for controlling MikroKopter
struct str_ExternControl externControlGier; //struct for controlling Yaw (Gier) only
 
u8 gamepad_values_convert_for_cam(int tmpvalue){
u8 tmp;
double tmpdouble = tmpvalue;
tmp = ((((tmpdouble/(MaxAxisValue))-1)*125)-131)*-1;
if(tmp == 0){tmp = 255;}
return(tmp);
}
 
//>> Converting gamepad values to values readable by a MikroKopter
//------------------------------------------------------------------------------------------------------
u8 gamepad_values_convert_for_kopter(int tmpvalue){
u8 tmp;
double tmpdouble = tmpvalue;
tmp = ((((tmpdouble/(MaxAxisValue*Sensitivity))-1)*125)-131)*-1;
/*Increase values exponentially
if(tmpvalue < 0){
tmpdouble = tmpvalue*-1;
}else{tmpdouble = tmpvalue;}
tmp = ((30497*tmpdouble*tmpdouble*tmpdouble)/11187226521286200+(10667778*tmpdouble*tmpdouble)/532725072442200+(2592340312*tmpdouble)/11187226521286);
if(tmpvalue < 0){
tmp = (tmp*-1)+255;
}
*/
return(tmp);
}
 
u8 gamepad_values_convert_for_kopter_gas(int tmpvalue){
u8 tmp;
double tmpdouble = tmpvalue;
tmp = ((((tmpdouble/(MaxAxisValue))-1)*125)-131)*-1;
return(tmp);
}
 
int check_if_button_pushed(){
read_gamepad_data();
int buttonpushed = -1;
for (int i = 0; i < NumberOfButtonsAvailiable; i++)
{
if(Button[i] != 0){
buttonpushed = i;
}
}
return(buttonpushed);
}
 
//>> Check if controls are active
//------------------------------------------------------------------------------------------------------
void check_if_controls_active(){
if(check_if_button_pushed() == GamepadLayout[17] && IsActive == 0){
IsActive = 1;
while(1){if(!value_sum(0)){break;};}
}else if(check_if_button_pushed() == GamepadLayout[17] && IsActive == 1){
IsActive = 0;
while(1){if(!value_sum(0)){break;};}
}
}
//>> Check if program has been switched
//------------------------------------------------------------------------------------------------------
void check_program_switch(){
if(check_if_button_pushed() == GamepadLayout[11]){
frame_print("", 1, 0);
ProgramSelect = 1;
}else if(check_if_button_pushed() == GamepadLayout[12]){
frame_print("", 1, 0);
ProgramSelect = 2;
}
}
 
//>> Check if sensitivity of the controls has been adjusted
//------------------------------------------------------------------------------------------------------
void get_sensitivity(){
if(check_if_button_pushed() == GamepadLayout[15] && Sensitivity <= 2.0){
if(Sensitivity < 2){buzzer_short(1);}
Sensitivity += 0.2;
while(1){if(!value_sum(0)){break;};}
}else if(check_if_button_pushed() == GamepadLayout[16] && Sensitivity > 1.0){
if(Sensitivity > 1){buzzer_short(1);}
Sensitivity -= 0.2;
while(1){if(!value_sum(0)){break;};}
}
}
 
//>> Preparing Data for remotely controlling a Camera-Gimbal
//------------------------------------------------------------------------------------------------------
void create_data_camera(serial_data_struct* pdata_package_camera_control, serial_data_struct* pdata_package_camera_control_gier){
pdata_package_camera_control->data[0] = gamepad_values_convert_for_cam(Axis[GamepadLayout[0]]); //Nick
pdata_package_camera_control->data[1] = gamepad_values_convert_for_cam(Axis[GamepadLayout[1]]); //Roll
pdata_package_camera_control->data[2] = gamepad_values_convert_for_cam(Axis[GamepadLayout[3]]); //
if(Button[GamepadLayout[8]] > 0){recordingButtonTemp = 131;}else if(Button[GamepadLayout[9]] > 0){recordingButtonTemp = 125;}
pdata_package_camera_control->data[3] = recordingButtonTemp;
if(Button[GamepadLayout[10]]){pdata_package_camera_control->data[4] = 131;}else{pdata_package_camera_control->data[4] = 125;}
int i = 5;
while(i < 12){
pdata_package_camera_control->data[i] = 0;
i++;
}
//Add Yaw (Gier)-funcionality
externControlGier.Gier = gamepad_values_convert_for_kopter(Axis[GamepadLayout[2]]);
externControlGier.Config = EC_VALID | EC_GAS_ADD;
externControlGier.Frame = 'z'; //character for echo
u8 *tmpData = (unsigned char *) &externControlGier;
for (int i = 0; i < pdata_package_camera_control_gier->cmdLength; ++i)
{
pdata_package_camera_control_gier->data[i] = tmpData[i];
}
 
//Print out values on screen
char tmpbuffer[255];
sprintf(tmpbuffer, "Nick: %d \n Roll: %d \n Gier: %d \n Zoom: %d \n Aufnahme: %d \n Auslösung: %d", pdata_package_camera_control->data[0], pdata_package_camera_control->data[1], pdata_package_camera_control_gier->data[2], pdata_package_camera_control->data[2], pdata_package_camera_control->data[3], pdata_package_camera_control->data[4]);
frame_values("VALUES", 5, 2);
frame_values(tmpbuffer, 5, 4);
}
 
//>> Preparing Data for remotely controlling a MikroKopter
//------------------------------------------------------------------------------------------------------
void create_data_kopter(serial_data_struct* pdata_package_kopter_control){
if(check_if_button_pushed() == GamepadLayout[13]){ //Motor start
externControl.Nick = 131;
externControl.Roll = 131;
externControl.Gier = 131;
externControl.Gas = 131;
}else if(check_if_button_pushed() == GamepadLayout[14]){ //Motor stop
externControl.Nick = 131;
externControl.Roll = 125;
externControl.Gier = 125;
externControl.Gas = 131;
}else{
externControl.Nick = gamepad_values_convert_for_kopter(Axis[GamepadLayout[4]]);
externControl.Roll = gamepad_values_convert_for_kopter(Axis[GamepadLayout[5]]);
externControl.Gier = gamepad_values_convert_for_kopter(Axis[GamepadLayout[6]]);
externControl.Gas = gamepad_values_convert_for_kopter_gas(Axis[GamepadLayout[7]]);
}
externControl.Config = EC_VALID | EC_GAS_ADD | EC_IGNORE_RC;
externControl.Frame = 'z'; //character for echo
u8 *tmpData = (unsigned char *) &externControl;
for (int i = 0; i < pdata_package_kopter_control->cmdLength; ++i)
{
pdata_package_kopter_control->data[i] = tmpData[i];
}
//Print out values on screen
char tmpbuffer[255];
sprintf(tmpbuffer, "Nick: %d \n Roll: %d \n Gier: %d \n Gas : %d \n", pdata_package_kopter_control->data[0], pdata_package_kopter_control->data[1], pdata_package_kopter_control->data[2], pdata_package_kopter_control->data[3]);
frame_values("VALUES", 5, 2);
frame_values(tmpbuffer, 5, 4);
}
 
void read_gamepad_data(){
read(padFd, &js, sizeof(struct js_event));
switch (js.type & ~JS_EVENT_INIT)
{
case JS_EVENT_AXIS:
Axis [ js.number ] = js.value;
break;
case JS_EVENT_BUTTON:
Button [ js.number ] = js.value;
break;
}
}
 
//>> Initialize Gamepad
//------------------------------------------------------------------------------------------------------
void gamepad_init(){
if((padFd = open(GAME_PAD, O_RDONLY)) == -1)
{
printf( "Couldn't open gamepad\n" );
}
ioctl( padFd, JSIOCGAXES, &NumberOfAxesAvailiable );
ioctl( padFd, JSIOCGBUTTONS, &NumberOfButtonsAvailiable );
ioctl( padFd, JSIOCGNAME(80), &GamepadConnected );
Axis = (int *) calloc( NumberOfAxesAvailiable, sizeof( int ) );
Button = (char *) calloc( NumberOfButtonsAvailiable, sizeof( char ) );
fcntl( padFd, F_SETFL, O_NONBLOCK ); /* use non-blocking mode */
}
/RaspberryPi/PiMoteSwitch/gamepad.h
0,0 → 1,29
#ifndef _GAMEPAD_H
#define _GAMEPAD_H
 
#define GAME_PAD "/dev/input/js0"
 
//Defines for external control
#define EC_VALID 0x01 // only valid if this is 1
#define EC_GAS_ADD 0x02 // if 1 -> use the GAS Value not as MAX
#define EC_IGNORE_RC 0x80 // if 1 -> for Flying without RC-Control
 
extern void gamepad_init();
extern void read_gamepad_data();
extern void create_data_camera(serial_data_struct* pdata_package_camera_control, serial_data_struct* pdata_package_camera_control_gier);
extern void create_data_kopter(serial_data_struct* pdata_package_kopter_control);
extern int check_if_button_pushed();
extern void check_if_controls_active();
extern void check_program_switch();
extern void get_sensitivity();
 
extern volatile int *Axis;
extern volatile char *Button;
extern volatile float Sensitivity;
extern int NumberOfAxesAvailiable;
extern int NumberOfButtonsAvailiable;
extern char GamepadConnected[30];
extern u8 IsActive;
extern u8 ProgramSelect;
 
#endif //_GAMEPAD_H
/RaspberryPi/PiMoteSwitch/gpio.c
0,0 → 1,59
#include "main.h"
#include "gpio.h"
 
// IO Acces
struct bcm2835_peripheral {
unsigned long addr_p;
int mem_fd;
void *map;
volatile unsigned int *addr;
};
struct bcm2835_peripheral gpio = {GPIO_BASE};
 
 
int map_peripheral(struct bcm2835_peripheral *p)
{
// Open /dev/mem
if ((p->mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
printf("Failed to open /dev/mem, try checking permissions.\n");
return -1;
}
p->map = mmap(
NULL,
BLOCK_SIZE,
PROT_READ|PROT_WRITE,
MAP_SHARED,
p->mem_fd, // File descriptor to physical memory virtual file '/dev/mem'
p->addr_p // address in physical map that we want this memory block to expose
);
if (p->map == MAP_FAILED) {
perror("mmap");
return -1;
}
p->addr = (volatile unsigned int *)p->map;
return 0;
}
void unmap_peripheral(struct bcm2835_peripheral *p) {
munmap(p->map, BLOCK_SIZE);
close(p->mem_fd);
}
 
void buzzer_short(int seq){
INP_GPIO(4);
OUT_GPIO(4);
for (int i = 0; i < seq; ++i)
{
if(seq > 1){usleep(50000);}
GPIO_SET = 1 << 4;
usleep(50000);
GPIO_CLR = 1 << 4;
}
}
 
void gpio_init(){
if(map_peripheral(&gpio) == -1)
{
printf("Failed to map the physical GPIO registers into the virtual memory space.\n");
}
}
/RaspberryPi/PiMoteSwitch/gpio.h
0,0 → 1,22
#ifndef _GPIO_H
#define _GPIO_H
 
#define BCM2708_PERI_BASE 0x20000000
#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) // GPIO controller
#define BLOCK_SIZE (4*1024)
 
extern struct bcm2835_peripheral gpio;
 
// GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x)
#define INP_GPIO(g) *(gpio.addr + ((g)/10)) &= ~(7<<(((g)%10)*3))
#define OUT_GPIO(g) *(gpio.addr + ((g)/10)) |= (1<<(((g)%10)*3))
#define SET_GPIO_ALT(g,a) *(gpio.addr + (((g)/10))) |= (((a)<=3?(a) + 4:(a)==4?3:2)<<(((g)%10)*3))
#define GPIO_SET *(gpio.addr + 7) // sets bits which are 1 ignores bits which are 0
#define GPIO_CLR *(gpio.addr + 10) // clears bits which are 1 ignores bits which are 0
#define GPIO_READ(g) *(gpio.addr + 13) &= (1<<(g))
 
// Exposes the physical address defined in the passed structure using mmap on /dev/mem
extern void gpio_init();
extern void buzzer_short(int seq);
 
#endif //_GPIO_H
/RaspberryPi/PiMoteSwitch/main.c
0,0 → 1,41
#include "main.h"
 
 
u8 FileExists;
serial_data_struct data_package_camera_control; //Data Package for controlling the Camera
serial_data_struct data_package_camera_control_gier; //Data Package for controlling the Gier-Axis of the MikroKopter
serial_data_struct data_package_kopter_control; //Data Package for controlling the MikroKopter
 
int main(void){
frame_init();
FileExists = file_init();
gamepad_init();
gpio_init();
calibration_init();
uart_init();
buzzer_short(3);
for (;;)
{
check_program_switch();
if(ProgramSelect == 1){
read_gamepad_data();
create_data_camera(&data_package_camera_control, &data_package_camera_control_gier);
create_serial_frame(1, 'y', 12, &data_package_camera_control); //address, Command ID, Serial Command Length, data
create_serial_frame(1, 'b', sizeof(struct str_ExternControl), &data_package_camera_control_gier); //Gier
transmit_data(&data_package_camera_control);
transmit_data(&data_package_camera_control_gier);
}
if(ProgramSelect == 2){
check_if_controls_active();
if(IsActive){
get_sensitivity();
read_gamepad_data();
create_data_kopter(&data_package_kopter_control);
create_serial_frame(1, 'b', sizeof(struct str_ExternControl), &data_package_kopter_control);
transmit_data(&data_package_kopter_control);
}
}
usleep(5000); //200hz
}
}
/RaspberryPi/PiMoteSwitch/main.h
0,0 → 1,26
#ifndef _MAIN_H
#define _MAIN_H
 
#include <curses.h>
#include <stdio.h>
#include <string.h>
#include <termios.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/joystick.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "frame.h"
#include "types.h"
#include "file.h"
#include "uart.h"
#include "gamepad.h"
#include "calibration.h"
#include "gpio.h"
 
extern void usleep(int);
 
#endif //_MAIN_H
/RaspberryPi/PiMoteSwitch/types.h
0,0 → 1,40
#ifndef _TYPES_H
#define _TYPES_H
 
typedef unsigned char u8;
typedef unsigned short u16;
 
typedef struct
{
u8 address;
u8 cmdID;
u8 data[1024];
u8 txrxdata[1024];
u8 collecting;
u8 position_package;
u16 cmdLength;
 
}__attribute__((packed)) serial_data_struct;
 
 
typedef struct
{
u8 c;
u8 data[1024];
u16 position_rx;
u16 count;
}__attribute__((packed)) data_rx_st;
 
 
struct str_ExternControl
{
signed char Nick;
signed char Roll;
signed char Gier;
signed char Gas;
unsigned char Frame; // will return a confirm frame with this value
unsigned char Config;
unsigned char free;
};
 
#endif //_TYPES_H
/RaspberryPi/PiMoteSwitch/uart.c
0,0 → 1,91
#include "main.h"
#include "uart.h"
 
int uart0_filestream = -1;
int usb_stream = -1;
int data_length; //length of transmitting data string
 
 
//>> Adding checksum and transmitting data
//------------------------------------------------------------------------------------------------------
void transmit_data(serial_data_struct* pdata_package){
if (uart0_filestream != -1)
{
int count = write(uart0_filestream, pdata_package->txrxdata, pdata_package->cmdLength);
if (count < 0)
{
printf("UART TX error\n");
}
}
}
 
//>> Adding address and command ID, encoding and checksum
//------------------------------------------------------------------------------------------------------
void create_serial_frame(u8 address, u8 cmdID, u16 cmdLength, serial_data_struct* pdata_package){
pdata_package->txrxdata[0] = '#';
pdata_package->txrxdata[1] = address + 'a';
pdata_package->txrxdata[2] = cmdID;
 
//encode data
u8 a,b,c;
int counter = 0;
int u = 3;
while(cmdLength){
if(cmdLength)
{
cmdLength--;
a = pdata_package->data[counter++];
}else{a = 0; counter++;};
if(cmdLength)
{
cmdLength--;
b = pdata_package->data[counter++];
}else{b = 0; counter++;};
if(cmdLength)
{
cmdLength--;
c = pdata_package->data[counter++];
}else{c = 0; counter++;};
pdata_package->txrxdata[u++] = '=' + (a >> 2);
pdata_package->txrxdata[u++] = '=' + (((a & 0x03) << 4) | ((b & 0xf0) >> 4));
pdata_package->txrxdata[u++] = '=' + (((b & 0x0f) << 2) | ((c & 0xc0) >> 6));
pdata_package->txrxdata[u++] = '=' + (c & 0x3f);
}
 
//add Checksum
u16 crc = 0;
u8 crc1, crc2;
for (int i = 0; i < u; i++)
{
crc += pdata_package->txrxdata[i];
}
crc %= 4096;
crc1 = '=' + crc / 64;
crc2 = '=' + crc % 64;
pdata_package->txrxdata[u++] = crc1;
pdata_package->txrxdata[u++] = crc2;
pdata_package->txrxdata[u++] = '\r';
 
pdata_package->cmdLength = u;
}
 
 
//>> Initializing serial interface
//------------------------------------------------------------------------------------------------------
void uart_init(){
uart0_filestream = open(SERIAL, O_RDWR | O_NOCTTY | O_NDELAY);
if (uart0_filestream == -1)
{
printf("Error - Unable to open UART. Ensure it is not in use by another application\n");
}
//UART Options
struct termios options;
tcgetattr(uart0_filestream, &options);
options.c_cflag = B57600 | CS8 | CLOCAL | CREAD;
options.c_iflag = IGNPAR;
options.c_oflag = 0;
options.c_lflag = 0;
tcflush(uart0_filestream, TCIFLUSH);
tcsetattr(uart0_filestream, TCSANOW, &options);
//UART Options
}
/RaspberryPi/PiMoteSwitch/uart.h
0,0 → 1,24
#ifndef _UART_H
#define _UART_H
 
//addresses
#define FC_address 1 //(b)
#define NC_address 2 //(c)
#define MK3MAG_address 3 //(d)
#define BL_CTRL_address 5 //(f)
 
//Command IDs
#define SERIAL_CHANNELS 'y'
#define EXTERNAL_CONTROL 'b'
 
 
#define SERIAL "/dev/ttyAMA0"
 
//struct js_event e;
 
extern void create_serial_frame(u8 address, u8 cmdID, u16 cmdLength, serial_data_struct* pdata_package);
extern void transmit_data(serial_data_struct* pdata_package);
extern void encode_data(serial_data_struct* pdata_package);
extern void uart_init();
 
#endif //_UART_H