view shore/shore.ino @ 3:d25e14956c65 default tip

Rework log transfer function code and tidy up
author Daniel O'Connor <darius@dons.net.au>
date Sat, 11 Jul 2015 17:44:39 +0930
parents 7d4ec58da1d8
children
line wrap: on
line source

#include <avr/pgmspace.h>

#include <Servo.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include "log_lookup.h"

// DFRobot I/O Expansion Shield V7 - http://www.dfrobot.com/wiki/index.php/IO_Expansion_Shield_for_Arduino_V7_SKU:DFR0265
// 2xPS3 joysticks connected like so
// Joy 1 Horizontal - Left/right   - AD0
// Joy 1 Vertical   - Forward/back - AD1
// Joy 1 Button     - Unused       - D2
// Joy 2 Horizontal - Unused       - AD2
// Joy 2 Vertical   - Up/down      - AD3
// Joy 2 Button     - Unused       - D3

// LCD panel
LiquidCrystal_I2C lcd(0x27, 16, 2);  // I/O expander is at 0x27, LCD is 16x2

void setup() {
	int byte;

	Serial.begin(115200);

	// Set joystick button pins as inputs
	pinMode(7, INPUT);
	pinMode(8, INPUT);

	lcd.init();
	lcd.backlight();
	lcd.print("Hello world!");
}

// Based on http://playground.arduino.cc/Main/Fscale
float
fscale(float originalMin, float originalMax, float newBegin,
    float newEnd, float inputValue, float curve) {
	float OriginalRange = 0;
	float NewRange = 0;
	float zeroRefCurVal = 0;
	float normalizedCurVal = 0;
	float rangedValue = 0;
	boolean invFlag = 0;

	// condition curve parameter
	// limit range
	if (curve > 10) curve = 10;
	if (curve < -10) curve = -10;

	curve = (curve * -.1) ; // - invert and scale - this seems more intuitive - postive numbers give more weight to high end on output
	curve = pow(10, curve); // convert linear scale into lograthimic exponent for other pow function

	/*
	  Serial.println(curve * 100, DEC);   // multply by 100 to preserve resolution
	  Serial.println();
	*/

	// Check for out of range inputValues
	if (inputValue < originalMin) {
		inputValue = originalMin;
	}
	if (inputValue > originalMax) {
		inputValue = originalMax;
	}

	// Zero Reference the values
	OriginalRange = originalMax - originalMin;

	if (newEnd > newBegin) {
		NewRange = newEnd - newBegin;
	} else {
		NewRange = newBegin - newEnd;
		invFlag = 1;
	}

	zeroRefCurVal = inputValue - originalMin;
	normalizedCurVal  =  zeroRefCurVal / OriginalRange;   // normalize to 0 - 1 float

	/*
	  Serial.print(OriginalRange, DEC);
	  Serial.print("   ");
	  Serial.print(NewRange, DEC);
	  Serial.print("   ");
	  Serial.println(zeroRefCurVal, DEC);
	  Serial.println();
	*/

	// Check for originalMin > originalMax  - the math for all other cases i.e. negative numbers seems to work out fine
	if (originalMin > originalMax) {
		return 0;
	}

	if (invFlag == 0) {
		rangedValue = (pow(normalizedCurVal, curve) * NewRange) + newBegin;

	} else {
		// invert the ranges
		rangedValue = newBegin - (pow(normalizedCurVal, curve) * NewRange);
	}

	return rangedValue;
}

void loop() {
	int joy1X, joy1Y, joy2X, joy2Y, but1, but2;
	int lint, rint, vint, ldir, rdir, vdir;
	float k, l, r, v, x, y, tmp;
	char lcdbuf[16 + 1]; // Buffer 1 line

	k = 1.5;

	joy1X = analogRead(A0);
	joy1Y = analogRead(A1);
	but1 = !digitalRead(7); // Buttons are active low
	joy2X = analogRead(A2);
	joy2Y = analogRead(A3);
	but2 = !digitalRead(8);

#if 0
	Serial.print("Joy 1 X: "); Serial.print(joy1X); Serial.print("  ");
	Serial.print("Y: "); Serial.print(joy1Y); Serial.print("   Button:  ");
	Serial.println(but1);
	Serial.print("Joy 2 X: "); Serial.print(joy2X); Serial.print("  ");
	Serial.print("Y: "); Serial.print(joy2Y); Serial.print("   Button:  ");
	Serial.println(but2);
#endif
	// Create deadband in the centre because they don't sit at 512
	if (joy1X > 500 && joy1X < 510) // Sits at 505
		joy1X = 512;
	if (joy1Y > 516 && joy1Y < 526) // Sits at 521
		joy1Y = 512;
	if (joy2X > 500 && joy2X < 510) // Sits at 505
		joy2X = 512;
	if (joy2Y > 520 && joy2Y < 530) // Sits at 525
		joy2Y = 512;

	// Convert each axis to -1..1
	x = ((float)joy1X - 512.0) / 512.0;
	y = ((float)joy1Y - 512.0) / 512.0;
	v = ((float)joy2Y - 512.0) / 512.0;

	// Mix 'joystick' input to left/right thrust (elevon mixing)
	// http://eastbay-rc.blogspot.com.au/2011/05/elevon-v-tail-mixing-calculations.html
	l =  1 * (x / 2 + y / 2);
        r = -1 * (x / 2 - y / 2);

	// Apply some gain so full forward is a max speed
	l *= 2.0;
	r *= 2.0;

	// Apply transfer function and limit
	tmp = fscale(0, 1, 0, 1, abs(l), -1.5);
#if 0
	Serial.print("L: "); Serial.print(l); Serial.print(" Tmp: "); Serial.print(tmp); Serial.println();
#endif
	l = tmp * (l < 0 ? -1 : 1);
	tmp = fscale(0, 1, 0, 1, abs(r), -1.5);
	r = tmp * (r < 0 ? -1 : 1);
	tmp = fscale(0, 1, 0, 1, abs(v), -1.5);
	v = tmp * (v < 0 ? -1 : 1);

	// Map values to -255..255
	lint = l * 255;
	rint = r * 255;
	vint = v * 255;

	Serial.print("L:");
	Serial.print(lint);
	Serial.print(" R:");
	Serial.print(rint);
	Serial.print(" V:");
	Serial.print(vint);
	Serial.println();

	snprintf(lcdbuf, sizeof(lcdbuf) - 1, "L%3dR%3dV%3d", lint, rint, vint);
	lcd.setCursor(0, 0);
	lcd.print(lcdbuf);
	snprintf(lcdbuf, sizeof(lcdbuf) - 1, "  B1: %d  B2: %d   ", but1, but2);
	lcd.setCursor(0, 1);
	lcd.print(lcdbuf);
	delay(200);
}

/*
 * Local variables:
 * mode: c++
 * End:
 */