Subversion Repositories Projects

Compare Revisions

Ignore whitespace Rev 1733 → Rev 1734

/Transportables_Koptertool/branch/PKT_V363a_V088n_MartinR/stick.c
0,0 → 1,383
/*****************************************************************************
* Copyright (C) 2008 Thomas Kaiser, thomas@ft-fanpage.de *
* Copyright (C) 2009 Peter "woggle" Mack, mac@denich.net *
* Copyright (C) 2011 Christian "Cebra" Brandtner, brandtner@brandtner.net *
* Copyright (C) 2011 Harald Bongartz *
* Copyright (C) 2012 Martin Runkel *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
* *
* Credits to: *
* Holger Buss & Ingo Busker from mikrokopter.de for the MK project + SVN *
* http://www.mikrokopter.de *
* Gregor "killagreg" Stobrawa for his version of the MK code *
* Thomas Kaiser "thkais" for the original project. See *
* http://www.ft-fanpage.de/mikrokopter/ *
* http://forum.mikrokopter.de/topic-4061-1.html *
* Claas Anders "CaScAdE" Rathje for providing the font and his C-OSD code *
* http://www.mylifesucks.de/oss/c-osd/ *
* Harald Bongartz "HaraldB" for providing his Ideas and Code for usibility*
*****************************************************************************/
 
 
#include "cpu.h"
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
 
#include <string.h>
#include <stdlib.h>
 
#include "lcd.h"
#include "timer.h"
#include "servo.h"
#include "messages.h"
#include "lipo.h"
#include "stick.h"
 
#define SERVO_CORRECT 3.125
 
 
#include <util/delay.h>
#include <inttypes.h>
#include <stdlib.h>
 
#include "main.h"
#include "uart1.h"
#include "usart.h"
 
 
#define LIMIT_MIN_MAX(value, min, max) {if(value <= min) value = min; else if(value >= max) value = max;}
 
int16_t Pos_Stick[12]; // 1,5mS
int16_t Pos_alt[5]; //
 
uint8_t BalkenPos = 0;
uint8_t Stick_Display = 0;
uint8_t serialChannelRichtung = 0;
uint8_t serialChannelConfig = 2;
 
 
//--------------------------------------------------------------
//
void joystick (void)
{
// uint8_t chg = 0;
// uint8_t Pos_Stick = 150; // 1,5mS
// uint8_t Pos_alt = 150; //
//int16_t Pos_Stick[12]; // 1,5mS
uint8_t chg = 0;
//uint8_t BalkenPos = 0;
uint8_t Stick_Nr = 0;
//uint8_t Stick_Display = 0;
uint8_t i = 0;
 
memset (Pos_Stick, 150, 3); // füllt 3+1 Byte vom Pos_Stick[12] mit 150
//int16_t Pos_alt[5]; //
int16_t Poti_Summe[5]; //
memset (Poti_Summe, 0, 5); // füllt 3+1 Byte mit 0
int16_t Poti_Neutral[5]; //
 
 
// ADC- init
Stick_Nr = 0;
ADMUX = (1<<REFS0)|(0<<MUX0); // Multiplexer selection Register: AVCC with external capacitor at AREF pin , ADC1
ADMUX = (ADMUX & ~(0x1F)) | (Stick_Nr & 0x1F); // ADC[Stick_Nr] verwenden
timer = 50;
while (timer > 0);
ADCSRA = (1<<ADEN)|(1<<ADSC)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); // ADC Enable, ADC Start, Prescaler 128
 
// Stick-Neutralposition bestimmen
 
while (ADCSRA & (1<<ADSC)); // wenn ADC fertig
Poti_Neutral[Stick_Nr] = ((ADCW>>2)&0xff);
LIMIT_MIN_MAX (Poti_Neutral[Stick_Nr],108,148);
Stick_Nr = 2 ;
ADMUX = (ADMUX & ~(0x1F)) | (Stick_Nr & 0x1F); // ADC[i] verwenden
// Stick_Nr 1,2,3 = Potis, Stick_Nr 1= Lipo
ADCSRA |= (1<<ADSC); // ADC Start
while (ADCSRA & (1<<ADSC)); // wenn ADC fertig
Poti_Neutral[Stick_Nr] = ((ADCW>>2)&0xff);
LIMIT_MIN_MAX (Poti_Neutral[Stick_Nr],108,148);
Stick_Nr = 0;
ADMUX = (ADMUX & ~(0x1F)) | (Stick_Nr & 0x1F); // ADC[i] verwenden
// Stick_Nr 1,2,3 = Potis, Stick_Nr 1= Lipo
ADCSRA |= (1<<ADSC); // ADC Start
 
 
 
//OCR1A = 150 * SERVO_CORRECT; // Servomitte
 
lcd_cls ();
// Kopfzeile und Rahmen zeichnen
lcd_printp (PSTR(" serielle Potis 1-5 "), 2);
//lcd_printp_at (7, 5, PSTR("%"), 0);
//lcd_printp_at (16, 5, PSTR("mS"), 0);
 
lcd_puts_at(0, 7, strGet(KEYLINE3), 0);
lcd_printp_at (18, 7, PSTR("\x19O\x18"), 0);
for (i=0 ; i< 5 ; i++)
{
BalkenPos = 12 + (i*8) ;
 
lcd_rect(3,BalkenPos, 120, 6, 1); // +-150% Rahmen
lcd_line(23,BalkenPos,23,(BalkenPos+6),1); // -100%
lcd_line(43,BalkenPos,43,(BalkenPos+6),1); // -50%
lcd_frect(62,BalkenPos, 2, 6, 1); // 0%
lcd_line(83,BalkenPos,83,(BalkenPos+6),1); // +50%
lcd_line(103,BalkenPos,103,(BalkenPos+6),1); // +100%
}
// Reset auf Mittelstellung
Pos_Stick[0] = 150;
Poti_Summe[0] = 0;
Pos_Stick[2] = 150;
Poti_Summe[2] = 0;
Pos_Stick[4] = 150;
Poti_Summe[4] = 0;
chg = 255;
 
do
{
if (!(ADCSRA & (1<<ADSC))) // wenn ADC fertig
{
//Pos_Stick[Stick_Nr] = 150 + 128 - ((ADCW>>2)&0xff);
if (serialChannelRichtung & (1<<Stick_Nr))
Pos_Stick[Stick_Nr] = Poti_Neutral[Stick_Nr] - ((ADCW>>2)&0xff);
else
Pos_Stick[Stick_Nr] = ((ADCW>>2)&0xff) - Poti_Neutral[Stick_Nr];
LIMIT_MIN_MAX (Pos_Stick[Stick_Nr],-120,120);
if ((Stick_Nr==0) || (Stick_Nr==2)) // nur die Potis 1,2 sind nicht neutralisierend
{
Poti_Summe[Stick_Nr] += (Pos_Stick[Stick_Nr]/8) * abs(Pos_Stick[Stick_Nr]/8);
LIMIT_MIN_MAX (Poti_Summe[Stick_Nr],-(120*128),(120*128));
Pos_Stick[Stick_Nr]= Poti_Summe[Stick_Nr] / 128; // nicht neutralisierend
}
Pos_Stick[Stick_Nr] += 150;
LIMIT_MIN_MAX (Pos_Stick[Stick_Nr],30,270); // war 75 , 225
if (Pos_Stick[Stick_Nr] != Pos_alt[Stick_Nr]) // nur bei Änderung
{
chg |= (1<<Stick_Nr) ;
//Pos_alt=Pos_Stick ; // verschoben
}
Stick_Nr ++ ;
//if (Stick_Nr==1) Stick_Nr=2; // Lipo überspringen
if (Stick_Nr==3) // Taster
{
// if (get_key_press (1 << KEY_EXT)) Pos_Stick[Stick_Nr] = 225;
if (serialChannelRichtung & (1<<Stick_Nr))
{
if (PINA & (1 << KEY_EXT)) Pos_Stick[Stick_Nr] = 30;
else Pos_Stick[Stick_Nr] = 270;
}
else
{
if (PINA & (1 << KEY_EXT)) Pos_Stick[Stick_Nr] = 270;
else Pos_Stick[Stick_Nr] = 30;
}
if (Pos_Stick[Stick_Nr] != Pos_alt[Stick_Nr])
{
chg |= (1<<Stick_Nr) ;
}
Stick_Nr=0;
}
/*
#ifndef ohne_Lipo // MartinR
Stick_Nr = 1; // MartinR AD-Kanal 1 überspringen wegen Lipo Überwachung
#endif
*/
ADMUX = (ADMUX & ~(0x1F)) | (Stick_Nr & 0x1F); // ADC[i] verwenden
// Stick_Nr 1,2,3 = Potis, Stick_Nr 0= Lipo
ADCSRA |= (1<<ADSC); // ADC Start
//serialPotis ();
}
 
if ((get_key_press (1 << KEY_PLUS) || get_key_long_rpt_sp ((1 << KEY_PLUS), 3)) && (Pos_Stick[4] < 271))
{
Pos_Stick[4] ++ ;
//LIMIT_MIN_MAX (Pos_Stick[Stick_Nr],30,270); // war 75 , 225
chg |= (1<<4) ;
}
else if ((get_key_press (1 << KEY_MINUS) || get_key_long_rpt_sp ((1 << KEY_MINUS), 3)) && (Pos_Stick[4] > 29))
{
Pos_Stick[4] -- ;
//LIMIT_MIN_MAX (Pos_Stick[Stick_Nr],30,270); // war 75 , 225
chg |= (1<<4) ;
}
else if (get_key_press (1 << KEY_ENTER))
{
/*
for (i=0 ; i< 4 ; i++)
{
BalkenPos = 12 + (i*8) ;
lcd_frect (4, (BalkenPos+1), 118, 4, 0); // Balken löschen
lcd_frect(62, BalkenPos, 2, 6, 1); // 0%
}
*/
Pos_Stick[0] = 150;
Poti_Summe[0] = 0;
Pos_Stick[2] = 150;
Poti_Summe[2] = 0;
Pos_Stick[4] = 150;
Poti_Summe[4] = 0;
BeepTime = 200;
BeepMuster = 0x0080;
chg = 255;
}
 
if (chg)
{
if (chg & (1<<0)); // Stick 1
{
BalkenPos = 12 + (0*8) ;
Stick_Display = 0;
Balken_Zeichnen () ;
Pos_alt[Stick_Display]=Pos_Stick[Stick_Display];
}
// Stick 2 = Lipo
if (chg & (1<<1)); // Stick 2
{
BalkenPos = 12 + (1*8) ;
Stick_Display = 1;
if (serialChannelConfig & (0<<1)) Balken_Zeichnen () ; // nur wenn keine Lipo-Spannung
Pos_alt[Stick_Display]=Pos_Stick[Stick_Display];
}
if (chg & (1<<2)); // Stick 3
{
BalkenPos = 12 + (2*8) ;
Stick_Display = 2;
Balken_Zeichnen () ;
Pos_alt[Stick_Display]=Pos_Stick[Stick_Display];
}
if (chg & (1<<3)); // Stick 4 = Taster
{
BalkenPos = 12 + (3*8) ;
Stick_Display = 3;
Balken_Zeichnen () ;
Pos_alt[Stick_Display]=Pos_Stick[Stick_Display];
}
if (chg & (1<<4)); // Stick 5 = Taster vom PKT
{
BalkenPos = 12 + (4*8) ;
Stick_Display = 4;
Balken_Zeichnen () ;
//OCR1A = (((Pos_Stick[Stick_Display]-150)/1.6)+150) * SERVO_CORRECT; // Servostellung , 1.6=0.8*0.5
Pos_alt[Stick_Display]=Pos_Stick[Stick_Display];
}
chg = 0;
serialPotis ();
}
}
while (!get_key_press (1 << KEY_ESC));
get_key_press(KEY_ALL);
#ifdef HWVERSION3_9
#ifndef ohne_Lipo // MartinR
ADC_Init(); // ADC für Lipomessung wieder aktivieren
#endif
#endif
 
}
 
//--------------------------------------------------------------
//
void serialPotis (void)
{
uint8_t i = 0;
memset (buffer, 0, 12); // füllt die 12+1 Byte vom buffer mit 0
 
for (i=0 ; i< 5 ; i++)
{
buffer[i] = Pos_Stick[i]-150 ;
}
SendOutData('y', ADDRESS_FC, 1, buffer, 12);
}
//--------------------------------------------------------------
//
void Balken_Zeichnen (void)
{
// Balken löschen
if ((Pos_Stick[Stick_Display] > Pos_alt[Stick_Display])&&(Pos_alt[Stick_Display] < 150)) // Balken links löschen
lcd_frect ((63-((150 -Pos_alt[Stick_Display]) * 0.5)), (BalkenPos+1), (63-((150- Pos_Stick[Stick_Display]) * 0.5)), 4, 0);
if ((Pos_Stick[Stick_Display] < Pos_alt[Stick_Display])&&(Pos_alt[Stick_Display] > 150)) // Balken rechts löschen
lcd_frect ((63+((Pos_Stick[Stick_Display] - 150) * 0.5)), (BalkenPos+1), (63+((Pos_alt[Stick_Display] - 150) * 0.5)), 4, 0);
// Balken zeichnen
if (Pos_Stick[Stick_Display] >= 150)
{
lcd_frect (63, (BalkenPos+1), ((Pos_Stick[Stick_Display] - 150) * 0.5), 4, 1);
//write_ndigit_number_u (4, 5, ((Pos_Stick[Stick_Display] - 150) * 1.25), 3, 0, 0); // Pulse width in %
lcd_frect(62, (BalkenPos), 2, 6, 1); // 0%
}
else
{
lcd_frect (63 - ((150 - Pos_Stick[Stick_Display]) * 0.5), (BalkenPos+1), ((150 - Pos_Stick[Stick_Display]) * 0.5), 4, 1);
//write_ndigit_number_u (4, 5, ((150 - Pos_Stick[Stick_Display]) * 1.25), 3, 0, 0); // Pulse width in %
lcd_frect(62, (BalkenPos), 2, 6, 1); // 0%
}
// Raster zeichnen
lcd_line(3, BalkenPos,3, (BalkenPos+6),1); // -150%
lcd_line(23, BalkenPos,23, (BalkenPos+6),1); // -100%
lcd_line(43, BalkenPos,43, (BalkenPos+6),1); // -50%
lcd_line(83, BalkenPos,83, (BalkenPos+6),1); // +50%
lcd_line(103,BalkenPos,103,(BalkenPos+6),1); // +100%
lcd_line(123,BalkenPos,123,(BalkenPos+6),1); // +150%
}