flipdot/flipcontrol_esp32/src/image.cpp

312 lines
7.7 KiB
C++

#include "image.h"
Image::Image()
{
}
void Image::serialPrintInt(uint16_t source)
{
for(uint8_t i = 0; i < 16; i++)
Serial.print((source & (1 << i)) > 0);
}
void Image::init()
{
flipdot.init(); //sets pin modes etc.
flag_updating=false;
update_counter=0;
updateDelay=10;
resetOrder(true);
}
uint8_t Image::getW() {
return COLUMNS;
}
uint8_t Image::getH() {
return ROWS;
}
void Image::setBuffer_solid(bool set)
{
for (uint8_t x=0;x<getW();x++) {
if (set) {
backBuffer[x]=0xffff; //all white
}else{
backBuffer[x]=0x0; //all black
}
}
flag_updating=true; //make update run
}
void Image::setBufferColumn(uint8_t _colnum, uint16_t _rowdata)
{
if (_colnum>=COLUMNS) {
Serial.println("colnum too high");
}else{
backBuffer[_colnum]=_rowdata; //all white
flag_updating=true; //make update run
}
}
void Image::setBuffer_random(uint8_t randomness)
{
for (uint8_t x=0;x<getW();x++) {
uint16_t randomnumber=0;
for (uint8_t y=0;y<getH();y++) {
if (random(256)<randomness) { //the higher the parameter the more white
randomnumber+=pow(2, y);
}
}
backBuffer[x]=randomnumber;
//backBuffer[x]=(uint16_t)random(0x10000);
}
flag_updating=true; //make update run
}
void Image::resetOrder(bool ascending) {
for (uint8_t i=0;i<getW();i++) { //fill with ascending numbers
if (ascending) {
orderArray[i]=i;
}else{
orderArray[i]=(getW()-1) - i;
}
}
}
void Image::shuffleOrder(uint8_t iterations) {
for (uint8_t s=0;s<iterations;s++) { //shuffle iterations
uint8_t _r1=random(getW());
uint8_t _r2=random(getW());
uint8_t _backup=orderArray[_r1];
//swap numbers
orderArray[_r1]=orderArray[_r2];
orderArray[_r2]=_backup;
}
for (uint8_t i=0;i<getW();i++) { //fill with ascending numbers
Serial.print(orderArray[i]); Serial.print(" ");
}
Serial.println();
}
UpdateReturn Image::updateByColumn(bool clearFirst, bool optimizeClear, bool optimizeSet)
{
if (!flag_updating) {
return nochange; //finished
}
if (millis()-lastUpdateMillis<updateDelay){ //too early
return wait; //not finished
}
unsigned long functionStartMillis=millis();
uint8_t x=update_counter/2;
bool setDot = (update_counter%2==1);
if (clearFirst) {
x=update_counter%getW();
setDot = !(update_counter/getW() == 0);
}
x = orderArray[x]; //use custom order
if (!setDot) { //even counter numbers are for clearing
uint16_t _colClear=frontBuffer[x]& ~backBuffer[x]; //Front & ~Back = Which bits have to be cleared
if (!optimizeClear || _colClear>0) { //at least on dot has to be cleared in this column
flipdot.setRow(0);
flipdot.selectColumnClear(x);
if (!flipdot.clearSelectedColumn()) {
Serial.println("Error clearing column!");
}
lastUpdateMillis=millis();
frontBuffer[x]=0;
}
}else{ //odd counter numbers are for setting
uint16_t _colSet=backBuffer[x]& ~frontBuffer[x];
if (!optimizeSet || _colSet>0) { //at least on dot has to be set in this column (if optimize is enabled)
flipdot.selectColumnSet(x); //lower column number is on the left
if (!optimizeSet) {
flipdot.setRow(backBuffer[x]); //flip all set dots in this column
}else{
flipdot.setRow(_colSet); //flip only currently not set dots in this column that have to be set
}
if (!flipdot.setSelectedDot()) {
Serial.println("Error setting dots!");
}
lastUpdateMillis=millis();
frontBuffer[x]=backBuffer[x]; //flip current column in buffer
}
}
update_counter++; //next column
unsigned long _duration=millis()-functionStartMillis; //how long it took to shift data and flip dots in this update
updateDuration=max(updateDuration,_duration); //store maximum value
if (update_counter/2>=getW()) { //reached last column
flag_updating=false;
update_counter=0;
return finished; //finished
}
return updating; //not finished
}
void Image::loop_testDots() {
static bool init=false;
if (!init) {
flipdot.setRow(0);
Serial.println("Clearing Display");
for (int l=0;l<COLUMNS;l++) {
flipdot.selectColumnClear(l%COLUMNS);
if (!flipdot.clearSelectedColumn()) {
Serial.println("Error clearing column!");
}else{
Serial.println("Cleared");
}
delay(50);
}
init=true;
Serial.println("Finished Clearing");
delay(1000);
}
Serial.println("Clearing");
flipdot.setRow(0);
flipdot.selectColumnClear(23);
if (!flipdot.clearSelectedColumn()) {
Serial.println("Error clearing column!");
}
delay(50);
flipdot.setRow(0);
flipdot.selectColumnClear(24);
if (!flipdot.clearSelectedColumn()) {
Serial.println("Error clearing column!");
}
delay(100);
Serial.println("Setting");
for (int i=23;i<25;i++) {
flipdot.selectColumnSet(i); //lower column number is on the left
flipdot.setRow(0);
flipdot.setRow(flipdot.getRow()+pow(2, 4));//low significant bits are lower rows (when connector at top)
flipdot.setRow(flipdot.getRow()+pow(2, 5));//low significant bits are lower rows (when connector at top)
flipdot.setSelectedDot();
delay(50);
}
delay(100);
countz++;
countz%=14;
//init=false;
}
void Image::loop_drawClearTest() {
static bool init=false;
if (!init) {
flipdot.setRow(0);
Serial.println("Clearing Display");
for (int l=0;l<COLUMNS;l++) {
flipdot.selectColumnClear(l%COLUMNS);
if (!flipdot.clearSelectedColumn()) {
Serial.println("Error clearing column!");
}else{
Serial.println("Cleared");
}
delay(20);
}
init=true;
delay(1000);
}
Serial.print("count=");
Serial.print(countz);Serial.print(": ");
//setting colX to 128, 32, 8,2 (or a combination of), then appling 12V to driver and GND to Clear, clears these colums
// this applies +12v to selected columns
//setting colX to 64,16,4,1 (or a combination of), then setting row shift registers to some setting sets the selected dots
// this applies GND to selected columns
//reset pin on annax board input should be used (not pulled to gnd for a short time) after dots have been flipped (to disable potentially activated transistors)
//cycle testing set dots
flipdot.selectColumnSet(countz/ROWS); //lower column number is on the left
flipdot.setRow(pow(2, (countz)%ROWS));//low significant bits are lower rows (when connector at top)
/*Serial.print("Row="); Serial.print(row); Serial.print(" Col=");
for (uint8_t i=0;i<7;i++) {
Serial.print(","); Serial.print(col[i]);
}
Serial.println();*/
//reset pin on ribbon cable high (12Vpullup/open), then low (via Transistor)
unsigned long starttime=micros();
flipdot.setSelectedDot();
unsigned long shiftduration=micros()-starttime;
Serial.println("");
Serial.print("Duration="); Serial.println(shiftduration);
countz++;
if (countz>=ROWS*COLUMNS) {
countz=0;
init=false;
}
}