Apparently I'm too new a user to post attachments so sorry for the long post.
// Motion control and general testing of multiple motors
// This is the main sourcecode to test CANbus control of the MyActuator RMD-X series with V???? firmware
// Uses Arduino Mega with the Sparkfun CAN-BUS shield
//
// National Geographic Photo Engineering
//
// Matt Norman
// May 20, 2022
#include <SPI.h>
#include <mcp_can.h>
#include "Ucglib.h"
// SAMD core //
#ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE
#define SERIAL SerialUSB
#else
#define SERIAL Serial
#endif
//# defines and constants //
#define LED2 8
#define LED3 7
#define CONTROL_PERIOD 10 // in MS
#define DIAL_PERIOD 250
#define NOISE_TOLERANCE 5
#define MAX_ACCELERATION 10000 // Max acceleration parameter 1 dps/LSB 0 - 10,000
#define MAX_SPEED 1000000 // Max speed parameter 1 dps/LSB -/+ 32767
#define MAX_DAMPING 32767 // Max acceleration parameter 1 dps/LSB 0 - 10,000
#define MAX_TORQUE 10000
#define T 4000
#define DLY() delay(2000)
unsigned long controlTimer = 0;
unsigned long currentTime = 0;
const int panPin = A0;
const int tiltPin = A1;
const int accPin = A3;
const int dampingPin = A2;
// cs pin = 10 for Uno = 53 for Mega //
const int SPI_CS_PIN = 10;
MCP_CAN CAN(SPI_CS_PIN); // Set CS pin //
Ucglib_ILI9341_18x240x320_SWSPI ucg(/*sclk=*/13, /*data=*/11, /*cd=*/9, /*cs=*/10, /*reset=*/8);
// func prototypes //
double mapVal(double, double, double, double, double);
int sendReceiveBuffer(uint16_t, unsigned char*, unsigned char*);
uint8_t checkInput();
uint8_t samplePin(uint8_t, int32_t*);
int32_t checkSoftStop(uint16_t, int8_t, int32_t, int32_t);
int32_t readPosition(uint16_t);
int32_t readAcceleration(uint16_t);
int32_t homeMotor(uint16_t);
int32_t initalizeMotor(uint16_t);
void brakeOffMotor(uint16_t);
void printBuffer(unsigned char*);
void readErrorState(uint16_t);
void readFirmwareVersion(uint16_t);
void resetMotor(uint16_t);
void runMotor(uint16_t);
void setSpeed(uint16_t, uint32_t);
void setAcceleration(uint16_t, uint32_t);
void spdCommand(uint16_t, uint32_t);
void stopMotor(uint16_t);
void zeroMotor(uint16_t);
// global variables //
unsigned char len = 0;
unsigned char buf[8];
uint8_t reductionRatio = 36; //gear box reduction 1:36 for RMD X6
uint8_t z = 127; // start value
uint16_t msgID = 0x140; //140+ID
uint32_t spdTilt = 5000; // speed, motor reduces by 0.01 dps/LSB or 0.1 dps/LSB depending on command
uint32_t spdPan = 5000; // speed, motor reduces by 0.01 dps/LSB or 0.1 dps/LSB depending on command
uint32_t lcg_rnd();
int32_t panLock = 135; //Pan Axis movment stops in deg
int32_t tiltLock = 90; //Tilt Axis movment stops in deg
int32_t angControl = 9000; //angle, motor reduces by 0.01 deg/LSB
int32_t currentPosTilt = 0; //current position of motor
int32_t currentPosPan = 0; //current position of motor
int32_t newPosTilt = 0; //next position of motor
int32_t newPosPan = 0; //next position of motor
int32_t currentAcceleration = 0; //current acceleration of motor
int32_t currentDamping = 0; //current damping of motor
int32_t tiltIn = 0;
int32_t panIn = 0;
int32_t homePan = 0;
int32_t homeTilt = 0;
double damping = 10000; // Movment damping
// runs once //
void setup() {
SERIAL.begin(115200);
// ucg.begin(UCG_FONT_MODE_TRANSPARENT);
// ucg.setFont(ucg_font_ncenR14_hr);
// ucg.clearScreen();
while (CAN_OK != CAN.begin(CAN_1000KBPS)) // init can bus : baudrate = 1000k
{
SERIAL.println("CAN BUS Shield init fail");
SERIAL.println(" Init CAN BUS Shield again");
delay(250);
}
SERIAL.println("CAN BUS Shield init ok!");
//Write LED pins low to turn them off by default
digitalWrite(LED2, LOW);
digitalWrite(LED3, LOW);
//Motor startup sequeance
SERIAL.println("Run Motor Startup");
homePan = initalizeMotor(0X141);
homeTilt = initalizeMotor(0X142);
checkInput();
}
uint8_t r = 0;
// runs continuous //
void loop() {
currentTime = millis();
if (checkInput()) {
if (samplePin(dampingPin, ¤tDamping)) {
damping = mapVal(currentDamping, 0, 1023, 0, 100) / 100;
}
if (samplePin(accPin, ¤tAcceleration)) {
setAcceleration(0x141, mapVal(currentAcceleration, 0, 1023, 0, MAX_ACCELERATION));
setAcceleration(0x142, mapVal(currentAcceleration, 0, 1023, 0, MAX_ACCELERATION));
}
// SERIAL.print("Pan Axis Status");
// SERIAL.println(checkSoftStop(0x141, 90, homePan));
// SERIAL.println(readPosition(0x141));
// SERIAL.print("Current Speed: ");
// SERIAL.print(mapVal(panIn, 0, 1023, -MAX_SPEED, MAX_SPEED));
// SERIAL.print(" | Damping Setting: ");
// SERIAL.print(damping);
// SERIAL.print(" | Acc Setting: ");
// SERIAL.print(mapVal(currentAcceleration, 0, 1023, 0, MAX_ACCELERATION));
// SERIAL.print(" | Acc Reading: ");
// SERIAL.println(readAcceleration(0x141));
}
if (currentTime - controlTimer >= CONTROL_PERIOD) {
controlTimer = currentTime;
setSpeed(0x141, damping * checkSoftStop(0x141, panPin, panLock, homePan));
setSpeed(0x142, damping * checkSoftStop(0x142, tiltPin, tiltLock, homeTilt));
// readErrorState( 0x142);
}
// switch (r & 3) {
// case 0: ucg.undoRotate(); break;
// case 1: ucg.setRotate90(); break;
// case 2: ucg.setRotate180(); break;
// default: ucg.setRotate270(); break;
// }
// if (r > 3) {
// ucg.clearScreen();
// set_clip_range();
// }
// r++;
// ucglib_graphics_test();
// // cross();
// pixel_and_lines();
// color_test();
// triangle();
// fonts();
// text();
// if (r <= 3)
// clip();
// box();
// gradient();
// //ucg.clearScreen();
// DLY();
// ucg.setMaxClipRange();
}
// Functions //
uint8_t checkInput() {
uint8_t pinState = 0;
pinState |= samplePin(panPin, &panIn);
pinState |= samplePin(tiltPin, &tiltIn);
return pinState;
}
uint8_t samplePin(uint8_t pin, int32_t* oldSample) {
// grab new sample
int32_t newSample = analogRead(pin);
// check if new sample is above noise threshold
if (abs(newSample - *oldSample) > NOISE_TOLERANCE) {
// update oldSample
*oldSample = newSample;
return 1;
}
return 0;
}
double mapVal(double valIn, double oldMin, double oldMax, double newMin, double newMax) {
double oldRange = oldMax - oldMin;
double newRange = newMax - newMin;
double valOut = 0.0;
valOut = (((valIn - oldMin) * newRange) / oldRange) + newMin;
if (valIn >= 500.0 && valIn <= 550.0) {
valOut = 0.0;
}
if (valOut > newMax) {
valOut = newMax;
}
if (valOut < newMin) {
valOut = newMin;
}
return valOut;
}
int32_t initalizeMotor(uint16_t canID) {
int32_t home = 0;
runMotor(canID);
delay(100);
zeroMotor(canID);
delay(100);
brakeOffMotor(canID);
delay(100);
resetMotor(canID);
delay(2500);
setAcceleration(canID, MAX_ACCELERATION);
delay(100);
home = homeMotor(canID);
return home;
}
int sendReceiveBuffer(uint16_t canId, unsigned char* buf_in, unsigned char* buf_out) {
int success_flag = 0; //Set success flag to zero
int try_index = 5; //Attempt send receive buffer 5 times
buf_out[0] = 0x88;
buf_out[1] = 0x00;
buf_out[2] = 0x00;
buf_out[3] = 0x00;
buf_out[4] = 0x00;
buf_out[5] = 0x00;
buf_out[6] = 0x00;
buf_out[7] = 0x00;
if (buf_in[0] == 0x76) //excepion as 0x76 does not recieve a return
{
success_flag = 1;
buf_out[0] = 0x76;
return (success_flag);
}
while ((buf_out[0] == 0x88) && (try_index--)) {
CAN.sendMsgBuf(canId, 0, 8, buf_in);
delay(10);
if (CAN_MSGAVAIL == CAN.checkReceive()) // check if data coming
{
CAN.readMsgBuf(&len, buf_out); // read data, len: data length, buf: data buf
unsigned long canId = CAN.getCanId();
if (buf_out[0] != 0x88) {
success_flag = 1;
}
}
}
return (success_flag); //Return a zero if message not received
}
void printBuffer(unsigned char* buf) {
SERIAL.print(buf[0], HEX);
SERIAL.print("\t");
SERIAL.print(buf[1], HEX);
SERIAL.print("\t");
SERIAL.print(buf[2], HEX);
SERIAL.print("\t");
SERIAL.print(buf[3], HEX);
SERIAL.print("\t");
SERIAL.print(buf[4], HEX);
SERIAL.print("\t");
SERIAL.print(buf[5], HEX);
SERIAL.print("\t");
SERIAL.print(buf[6], HEX);
SERIAL.print("\t");
SERIAL.println(buf[7], HEX);
}
void readFirmwareVersion(uint16_t canID) {
unsigned char buf_in[8];
unsigned char buf_out[8];
//Read Firmware Version
buf_in[0] = 0xB2;
buf_in[1] = 0x00;
buf_in[2] = 0x00;
buf_in[3] = 0x00;
buf_in[4] = 0x00;
buf_in[5] = 0x00;
buf_in[6] = 0x00;
buf_in[7] = 0x00;
sendReceiveBuffer(canID, buf_in, buf_out);
}
void runMotor(uint16_t canID) {
unsigned char buf_in[8];
unsigned char buf_out[8];
//Motor ruunning command, legacy from v2.0??
buf_in[0] = 0x88;
buf_in[1] = 0x00;
buf_in[2] = 0x00;
buf_in[3] = 0x00;
buf_in[4] = 0x00;
buf_in[5] = 0x00;
buf_in[6] = 0x00;
buf_in[7] = 0x00;
sendReceiveBuffer(canID, buf_in, buf_out);
}
void brakeOffMotor(uint16_t canID) {
unsigned char buf_in[8];
unsigned char buf_out[8];
//Brake Off Command
buf_in[0] = 0x77;
buf_in[1] = 0x00;
buf_in[2] = 0x00;
buf_in[3] = 0x00;
buf_in[4] = 0x00;
buf_in[5] = 0x00;
buf_in[6] = 0x00;
buf_in[7] = 0x00;
sendReceiveBuffer(canID, buf_in, buf_out);
}
void brakeOnMotor(uint16_t canID) {
unsigned char buf_in[8];
unsigned char buf_out[8];
//Brake Off Command
buf_in[0] = 0x78;
buf_in[1] = 0x00;
buf_in[2] = 0x00;
buf_in[3] = 0x00;
buf_in[4] = 0x00;
buf_in[5] = 0x00;
buf_in[6] = 0x00;
buf_in[7] = 0x00;
sendReceiveBuffer(canID, buf_in, buf_out);
}
void zeroMotor(uint16_t canID) {
unsigned char buf_in[8];
unsigned char buf_out[8];
// set current position as zero
buf_in[0] = 0x64;
buf_in[1] = 0x00;
buf_in[2] = 0x00;
buf_in[3] = 0x00;
buf_in[4] = 0x00;
buf_in[5] = 0x00;
buf_in[6] = 0x00;
buf_in[7] = 0x00;
sendReceiveBuffer(canID, buf_in, buf_out);
}
int32_t homeMotor(uint16_t canID) {
int32_t tempHome[4];
// motor homing sequence
setPosition(canID, 180);
tempHome[0] = readPosition(canID);
setPosition(canID, 185);
setPosition(canID, 180);
tempHome[1] = readPosition(canID);
setPosition(canID, 175);
setPosition(canID, 180);
tempHome[2] = readPosition(canID);
tempHome[3] = (tempHome[0] + tempHome[1] + tempHome[2]) / 3;
SERIAL.print("Home Complete ");
SERIAL.println(canID, HEX);
return tempHome[3];
}
void resetMotor(uint16_t canID) {
unsigned char buf_in[8];
unsigned char buf_out[8];
// motor reset, necassary for zero position write to take effect
buf_in[0] = 0x76;
buf_in[1] = 0x00;
buf_in[2] = 0x00;
buf_in[3] = 0x00;
buf_in[4] = 0x00;
buf_in[5] = 0x00;
buf_in[6] = 0x00;
buf_in[7] = 0x00;
sendReceiveBuffer(canID, buf_in, buf_out);
}
void setPosition(uint16_t canID, uint32_t pos) {
unsigned char buf_in[8];
unsigned char buf_out[8];
pos = pos * 100 * reductionRatio;
//Send incremental position
buf_in[0] = 0xA4;
buf_in[1] = 0x00;
buf_in[2] = MAX_SPEED;
buf_in[3] = MAX_SPEED >> 8;
buf_in[4] = pos;
buf_in[5] = pos >> 8;
buf_in[6] = pos >> 16;
buf_in[7] = pos >> 24;
sendReceiveBuffer(canID, buf_in, buf_out);
delay(750);
}
void setSpeed(uint16_t canID, uint32_t spd) {
unsigned char buf_in[8];
unsigned char buf_out[8];
if (spd == 0) {
stopMotor(canID);
}
//Send incremental speed
buf_in[0] = 0xA2;
buf_in[1] = 0x00;
buf_in[2] = 0x00;
buf_in[3] = 0x00;
buf_in[4] = spd;
buf_in[5] = spd >> 8;
buf_in[6] = spd >> 16;
buf_in[7] = spd >> 24;
sendReceiveBuffer(canID, buf_in, buf_out);
}
void setAcceleration(uint16_t canID, uint32_t acc) {
unsigned char buf_in[8];
unsigned char buf_out[8];
//Send incremental acceleration
buf_in[0] = 0x43;
buf_in[1] = 0x00;
buf_in[2] = 0x00;
buf_in[3] = 0x00;
buf_in[4] = acc;
buf_in[5] = acc >> 8;
buf_in[6] = acc >> 16;
buf_in[7] = acc >> 24;
sendReceiveBuffer(canID, buf_in, buf_out);
}
void stopMotor(uint16_t canID) {
unsigned char buf_in[8];
unsigned char buf_out[8];
//stop motor movment
buf_in[0] = 0x81;
buf_in[1] = 0x00;
buf_in[2] = 0x00;
buf_in[3] = 0x00;
buf_in[4] = 0x00;
buf_in[5] = 0x00;
buf_in[6] = 0x00;
buf_in[7] = 0x00;
sendReceiveBuffer(canID, buf_in, buf_out);
}
void readMode(uint16_t canID) {
unsigned char buf_in[8];
unsigned char buf_out[8];
//stop motor movment
buf_in[0] = 0x70;
buf_in[1] = 0x00;
buf_in[2] = 0x00;
buf_in[3] = 0x00;
buf_in[4] = 0x00;
buf_in[5] = 0x00;
buf_in[6] = 0x00;
buf_in[7] = 0x00;
sendReceiveBuffer(canID, buf_in, buf_out);
}
int32_t checkSoftStop(uint16_t canID, int8_t pin, int32_t stop, int32_t homePosition) {
int32_t currentPosition = readPosition(canID); // in 1deg/lsb
int32_t negStop = homePosition - stop;
int32_t posStop = homePosition + stop;
int32_t speed = 0;
if (currentPosition <= negStop) {
// setSpeed(canID, 0);
setPosition(canID, (negStop + 1));
speed = 0;
} else if (currentPosition >= posStop) {
// setSpeed(canID, 0);
setPosition(canID, (posStop - 1));
speed = 0;
} else {
speed = mapVal(analogRead(pin), 0, 1023, -MAX_SPEED, MAX_SPEED);
}
return speed;
}
int32_t readPosition(uint16_t canID) {
unsigned char buf_in[8];
unsigned char buf_out[8];
int32_t pos = 0;
//read current position
buf_in[0] = 0x92;
buf_in[1] = 0x00;
buf_in[2] = 0x00;
buf_in[3] = 0x00;
buf_in[4] = 0x00;
buf_in[5] = 0x00;
buf_in[6] = 0x00;
buf_in[7] = 0x00;
sendReceiveBuffer(canID, buf_in, buf_out);
pos = ((uint32_t)buf_out[7] << 24) | ((uint32_t)buf_out[6] << 16) | ((uint32_t)buf_out[5] << 8) | ((uint32_t)buf_out[4]);
pos = pos / 100 / reductionRatio;
// pos = ((uint32_t)buf_out[7] << 8) | ((uint32_t)buf_out[6]);
return pos;
}
int32_t readAcceleration(uint16_t canID) {
unsigned char buf_in[8];
unsigned char buf_out[8];
int32_t acc = 0;
//read current position
buf_in[0] = 0x42;
buf_in[1] = 0x00;
buf_in[2] = 0x00;
buf_in[3] = 0x00;
buf_in[4] = 0x00;
buf_in[5] = 0x00;
buf_in[6] = 0x00;
buf_in[7] = 0x00;
sendReceiveBuffer(canID, buf_in, buf_out);
acc = ((uint32_t)buf_out[7] << 24) | ((uint32_t)buf_out[6] << 16) | ((uint32_t)buf_out[5] << 8) | ((uint32_t)buf_out[4]);
return acc;
}
void readErrorState(uint16_t canID) {
unsigned char buf_in[8];
unsigned char buf_out[8];
int8_t temp = 0;
int8_t brake = 0;
int16_t voltage = 0;
int16_t errStat = 0;
int16_t torqueCurrent = 0;
int16_t motorSpeed = 0;
int16_t outputAngle = 0;
//read error frame one
buf_in[0] = 0x9A;
buf_in[1] = 0x00;
buf_in[2] = 0x00;
buf_in[3] = 0x00;
buf_in[4] = 0x00;
buf_in[5] = 0x00;
buf_in[6] = 0x00;
buf_in[7] = 0x00;
sendReceiveBuffer(canID, buf_in, buf_out);
temp = buf_out[1];
brake = buf_out[3];
voltage = (((uint16_t)buf_out[5] << 8) | ((uint16_t)buf_out[4]));
errStat = (((uint16_t)buf_out[7] << 8) | ((uint16_t)buf_out[6]));
//read error frame two
buf_in[0] = 0x9C;
buf_in[1] = 0x00;
buf_in[2] = 0x00;
buf_in[3] = 0x00;
buf_in[4] = 0x00;
buf_in[5] = 0x00;
buf_in[6] = 0x00;
buf_in[7] = 0x00;
sendReceiveBuffer(canID, buf_in, buf_out);
torqueCurrent = (((uint16_t)buf_out[3] << 8) | ((uint16_t)buf_out[2]));
motorSpeed = (((uint16_t)buf_out[5] << 8) | ((uint16_t)buf_out[4]));
outputAngle = (((uint16_t)buf_out[7] << 8) | ((uint16_t)buf_out[6]));
SERIAL.println("");
SERIAL.print("Motor Temp: ");
SERIAL.println(temp);
SERIAL.print("Brake State: ");
SERIAL.println(brake);
SERIAL.print("Voltage: ");
SERIAL.println(voltage);
SERIAL.print("Error State: ");
SERIAL.println(errStat);
SERIAL.print("Torque Current: ");
SERIAL.println(torqueCurrent);
SERIAL.print("Motor Speed: ");
SERIAL.println(motorSpeed);
SERIAL.print("Output Angle: ");
SERIAL.println(outputAngle);
}
uint32_t lcg_rnd(void) {
z = (uint8_t)((uint16_t)65 * (uint16_t)z + (uint16_t)17);
return (uint32_t)z;
}
void ucglib_graphics_test(void) {
//ucg.setMaxClipRange();
ucg.setColor(0, 0, 40, 80);
ucg.setColor(1, 80, 0, 40);
ucg.setColor(2, 255, 0, 255);
ucg.setColor(3, 0, 255, 255);
ucg.drawGradientBox(0, 0, ucg.getWidth(), ucg.getHeight());
ucg.setColor(255, 168, 0);
ucg.setPrintDir(0);
ucg.setPrintPos(2, 18);
ucg.print("Ucglib");
ucg.setPrintPos(2, 18 + 20);
ucg.print("GraphicsTest");
DLY();
}
void gradient(void) {
ucg.setColor(0, 0, 255, 0);
ucg.setColor(1, 255, 0, 0);
ucg.setColor(2, 255, 0, 255);
ucg.setColor(3, 0, 255, 255);
ucg.drawGradientBox(0, 0, ucg.getWidth(), ucg.getHeight());
ucg.setColor(255, 255, 255);
ucg.setPrintPos(2, 18);
ucg.setPrintDir(0);
ucg.print("GradientBox");
ucg.setColor(0, 0, 255, 0);
ucg.drawBox(2, 25, 8, 8);
ucg.setColor(0, 255, 0, 0);
ucg.drawBox(2 + 10, 25, 8, 8);
ucg.setColor(0, 255, 0, 255);
ucg.drawBox(2, 25 + 10, 8, 8);
ucg.setColor(0, 0, 255, 255);
ucg.drawBox(2 + 10, 25 + 10, 8, 8);
DLY();
}
void box(void) {
ucg_int_t x, y, w, h;
unsigned long m;
ucg.setColor(0, 0, 40, 80);
ucg.setColor(1, 60, 0, 40);
ucg.setColor(2, 128, 0, 140);
ucg.setColor(3, 0, 128, 140);
ucg.drawGradientBox(0, 0, ucg.getWidth(), ucg.getHeight());
ucg.setColor(255, 255, 255);
ucg.setPrintPos(2, 18);
ucg.setPrintDir(0);
ucg.print("Box");
m = millis() + T;
while (millis() < m) {
ucg.setColor((lcg_rnd() & 127) + 127, (lcg_rnd() & 127) + 64, lcg_rnd() & 31);
w = lcg_rnd() & 31;
h = lcg_rnd() & 31;
w += 10;
h += 10;
x = (lcg_rnd() * (ucg.getWidth() - w)) >> 8;
y = (lcg_rnd() * (ucg.getHeight() - h - 20)) >> 8;
ucg.drawBox(x, y + 20, w, h);
}
}
void pixel_and_lines(void) {
ucg_int_t mx;
ucg_int_t x, xx;
mx = ucg.getWidth() / 2;
//my = ucg.getHeight() / 2;
ucg.setColor(0, 0, 0, 150);
ucg.setColor(1, 0, 60, 40);
ucg.setColor(2, 60, 0, 40);
ucg.setColor(3, 120, 120, 200);
ucg.drawGradientBox(0, 0, ucg.getWidth(), ucg.getHeight());
ucg.setColor(255, 255, 255);
ucg.setPrintPos(2, 18);
ucg.setPrintDir(0);
ucg.print("Pix&Line");
ucg.drawPixel(0, 0);
ucg.drawPixel(1, 0);
//ucg.drawPixel(ucg.getWidth()-1, 0);
//ucg.drawPixel(0, ucg.getHeight()-1);
ucg.drawPixel(ucg.getWidth() - 1, ucg.getHeight() - 1);
ucg.drawPixel(ucg.getWidth() - 1 - 1, ucg.getHeight() - 1);
for (x = 0; x < mx; x++) {
xx = (((uint16_t)x) * 255) / mx;
ucg.setColor(255, 255 - xx / 2, 255 - xx);
ucg.drawPixel(x, 24);
ucg.drawVLine(x + 7, 26, 13);
}
DLY();
}
void color_test(void) {
ucg_int_t mx;
uint16_t c, x;
mx = ucg.getWidth() / 2;
//my = ucg.getHeight() / 2;
ucg.setColor(0, 0, 0, 0);
ucg.drawBox(0, 0, ucg.getWidth(), ucg.getHeight());
ucg.setColor(255, 255, 255);
ucg.setPrintPos(2, 18);
ucg.setPrintDir(0);
ucg.print("Color Test");
ucg.setColor(0, 127, 127, 127);
ucg.drawBox(0, 20, 16 * 4 + 4, 5 * 8 + 4);
for (c = 0, x = 2; c <= 255; c += 17, x += 4) {
ucg.setColor(0, c, c, c);
ucg.drawBox(x, 22, 4, 8);
ucg.setColor(0, c, 0, 0);
ucg.drawBox(x, 22 + 8, 4, 8);
ucg.setColor(0, 0, c, 0);
ucg.drawBox(x, 22 + 2 * 8, 4, 8);
ucg.setColor(0, 0, 0, c);
ucg.drawBox(x, 22 + 3 * 8, 4, 8);
ucg.setColor(0, c, 255 - c, 0);
ucg.drawBox(x, 22 + 4 * 8, 4, 8);
}
DLY();
}
void cross(void) {
ucg_int_t mx, my;
ucg.setColor(0, 250, 0, 0);
ucg.setColor(1, 255, 255, 30);
ucg.setColor(2, 220, 235, 10);
ucg.setColor(3, 205, 0, 30);
ucg.drawGradientBox(0, 0, ucg.getWidth(), ucg.getHeight());
mx = ucg.getWidth() / 2;
my = ucg.getHeight() / 2;
ucg.setColor(0, 255, 255, 255);
ucg.setPrintPos(2, 18);
ucg.print("Cross");
ucg.setColor(0, 0, 0x66, 0xcc);
ucg.setPrintPos(mx + 15, my - 5);
ucg.print("dir0");
ucg.setPrintPos(mx + 5, my + 26);
ucg.print("dir1");
ucg.setPrintPos(mx - 40, my + 20);
ucg.print("dir2");
ucg.setPrintPos(mx + 5, my - 25);
ucg.print("dir3");
ucg.setColor(0, 0, 0x66, 0xff);
ucg.setColor(1, 0, 0x66, 0xcc);
ucg.setColor(2, 0, 0, 0x99);
ucg_Draw90Line(ucg.getUcg(), mx + 2, my - 1, 20, 0, 0);
ucg_Draw90Line(ucg.getUcg(), mx + 2, my, 20, 0, 1);
ucg_Draw90Line(ucg.getUcg(), mx + 2, my + 1, 20, 0, 2);
ucg_Draw90Line(ucg.getUcg(), mx + 1, my + 2, 20, 1, 0);
ucg_Draw90Line(ucg.getUcg(), mx, my + 2, 20, 1, 1);
ucg_Draw90Line(ucg.getUcg(), mx - 1, my + 2, 20, 1, 2);
ucg_Draw90Line(ucg.getUcg(), mx - 2, my + 1, 20, 2, 0);
ucg_Draw90Line(ucg.getUcg(), mx - 2, my, 20, 2, 1);
ucg_Draw90Line(ucg.getUcg(), mx - 2, my - 1, 20, 2, 2);
ucg_Draw90Line(ucg.getUcg(), mx - 1, my - 2, 20, 3, 0);
ucg_Draw90Line(ucg.getUcg(), mx, my - 2, 20, 3, 1);
ucg_Draw90Line(ucg.getUcg(), mx + 1, my - 2, 20, 3, 2);
DLY();
}
void triangle(void) {
unsigned long m;
ucg.setColor(0, 0, 80, 20);
ucg.setColor(1, 60, 80, 20);
ucg.setColor(2, 60, 120, 0);
ucg.setColor(3, 0, 140, 30);
ucg.drawGradientBox(0, 0, ucg.getWidth(), ucg.getHeight());
ucg.setColor(255, 255, 255);
ucg.setPrintPos(2, 18);
ucg.print("Triangle");
m = millis() + T;
while (millis() < m) {
ucg.setColor((lcg_rnd() & 127) + 127, lcg_rnd() & 31, (lcg_rnd() & 127) + 64);
ucg.drawTriangle(
(lcg_rnd() * (ucg.getWidth())) >> 8,
((lcg_rnd() * (ucg.getHeight() - 20)) >> 8) + 20,
(lcg_rnd() * (ucg.getWidth())) >> 8,
((lcg_rnd() * (ucg.getHeight() - 20)) >> 8) + 20,
(lcg_rnd() * (ucg.getWidth())) >> 8,
((lcg_rnd() * (ucg.getHeight() - 20)) >> 8) + 20);
}
}
void text(void) {
ucg_int_t x, y, w, h, i;
unsigned long m;
ucg.setColor(0, 80, 40, 0);
ucg.setColor(1, 60, 0, 40);
ucg.setColor(2, 20, 0, 20);
ucg.setColor(3, 60, 0, 0);
ucg.drawGradientBox(0, 0, ucg.getWidth(), ucg.getHeight());
ucg.setColor(255, 255, 255);
ucg.setPrintPos(2, 18);
ucg.setPrintDir(0);
ucg.print("Text");
m = millis() + T;
i = 0;
while (millis() < m) {
ucg.setColor(lcg_rnd() & 31, (lcg_rnd() & 127) + 127, (lcg_rnd() & 127) + 64);
w = 40;
h = 22;
x = (lcg_rnd() * (ucg.getWidth() - w)) >> 8;
y = (lcg_rnd() * (ucg.getHeight() - h)) >> 8;
ucg.setPrintPos(x, y + h);
ucg.setPrintDir((i >> 2) & 3);
i++;
ucg.print("Ucglib");
}
ucg.setPrintDir(0);
}
void fonts(void) {
ucg_int_t d = 5;
ucg.setColor(0, 0, 40, 80);
ucg.setColor(1, 150, 0, 200);
ucg.setColor(2, 60, 0, 40);
ucg.setColor(3, 0, 160, 160);
ucg.drawGradientBox(0, 0, ucg.getWidth(), ucg.getHeight());
ucg.setColor(255, 255, 255);
ucg.setPrintDir(0);
ucg.setPrintPos(2, 18);
ucg.print("Fonts");
ucg.setFontMode(UCG_FONT_MODE_TRANSPARENT);
ucg.setColor(255, 200, 170);
ucg.setFont(ucg_font_helvB08_hr);
ucg.setPrintPos(2, 30 + d);
ucg.print("ABC abc 123");
ucg.setFont(ucg_font_helvB10_hr);
ucg.setPrintPos(2, 45 + d);
ucg.print("ABC abc 123");
ucg.setFont(ucg_font_helvB12_hr);
//ucg.setPrintPos(2,62+d);
//ucg.print("ABC abc 123");
ucg.drawString(2, 62 + d, 0, "ABC abc 123"); // test drawString
ucg.setFontMode(UCG_FONT_MODE_SOLID);
ucg.setColor(255, 200, 170);
ucg.setColor(1, 0, 100, 120); // background color in solid mode
ucg.setFont(ucg_font_helvB08_hr);
ucg.setPrintPos(2, 75 + 30 + d);
ucg.print("ABC abc 123");
ucg.setFont(ucg_font_helvB10_hr);
ucg.setPrintPos(2, 75 + 45 + d);
ucg.print("ABC abc 123");
ucg.setFont(ucg_font_helvB12_hr);
ucg.setPrintPos(2, 75 + 62 + d);
ucg.print("ABC abc 123");
ucg.setFontMode(UCG_FONT_MODE_TRANSPARENT);
/* big fonts removed, some trouble with the Arduino IDE */
/*
ucg.setFont(ucg_font_helvB14_hr);
ucg.setPrintPos(2,79+d);
ucg.print("ABC abc 123");
ucg.setFont(ucg_font_helvB18_hr);
ucg.setPrintPos(2,79+22+d);
ucg.print("ABC abc 123");
*/
ucg.setFont(ucg_font_ncenR14_hr);
DLY();
}
void clip(void) {
ucg.setColor(0, 0x00, 0xd1, 0x5e); // dark green
ucg.setColor(1, 0xff, 0xf7, 0x61); // yellow
ucg.setColor(2, 0xd1, 0xc7, 0x00); // dark yellow
ucg.setColor(3, 0x61, 0xff, 0xa8); // green
ucg.drawGradientBox(0, 0, ucg.getWidth(), ucg.getHeight());
ucg.setColor(255, 255, 255);
ucg.setPrintPos(2, 18);
ucg.setPrintDir(0);
ucg.print("ClipRange");
ucg.setColor(0xd1, 0x00, 0x073);
ucg.setFont(ucg_font_helvB18_hr);
ucg.setPrintPos(25, 45);
ucg.setPrintDir(0);
ucg.print("Ucg");
ucg.setPrintDir(1);
ucg.print("Ucg");
ucg.setPrintDir(2);
ucg.print("Ucg");
ucg.setPrintDir(3);
ucg.print("Ucg");
ucg.setMaxClipRange();
ucg.setColor(0xff, 0xff, 0xff);
ucg.drawFrame(20 - 1, 30 - 1, 15 + 2, 20 + 2);
ucg.setClipRange(20, 30, 15, 20);
ucg.setColor(0xff, 0x61, 0x0b8);
ucg.setPrintPos(25, 45);
ucg.setPrintDir(0);
ucg.print("Ucg");
ucg.setPrintDir(1);
ucg.print("Ucg");
ucg.setPrintDir(2);
ucg.print("Ucg");
ucg.setPrintDir(3);
ucg.print("Ucg");
ucg.setMaxClipRange();
ucg.setColor(0xff, 0xff, 0xff);
ucg.drawFrame(60 - 1, 35 - 1, 25 + 2, 18 + 2);
ucg.setClipRange(60, 35, 25, 18);
ucg.setColor(0xff, 0x61, 0x0b8);
ucg.setPrintPos(25, 45);
ucg.setPrintDir(0);
ucg.print("Ucg");
ucg.setPrintDir(1);
ucg.print("Ucg");
ucg.setPrintDir(2);
ucg.print("Ucg");
ucg.setPrintDir(3);
ucg.print("Ucg");
ucg.setMaxClipRange();
ucg.setColor(0xff, 0xff, 0xff);
ucg.drawFrame(7 - 1, 58 - 1, 90 + 2, 4 + 2);
ucg.setClipRange(7, 58, 90, 4);
ucg.setColor(0xff, 0x61, 0x0b8);
ucg.setPrintPos(25, 45);
ucg.setPrintDir(0);
ucg.print("Ucg");
ucg.setPrintDir(1);
ucg.print("Ucg");
ucg.setPrintDir(2);
ucg.print("Ucg");
ucg.setPrintDir(3);
ucg.print("Ucg");
ucg.setFont(ucg_font_ncenR14_hr);
ucg.setMaxClipRange();
DLY();
}
void set_clip_range(void) {
ucg_int_t x, y, w, h;
w = lcg_rnd() & 31;
h = lcg_rnd() & 31;
w += 25;
h += 25;
x = (lcg_rnd() * (ucg.getWidth() - w)) >> 8;
y = (lcg_rnd() * (ucg.getHeight() - h)) >> 8;
ucg.setClipRange(x, y, w, h);
}
// END FILE