Andreas Kahler
/
OsciPaint
Paints a rotating FabLab Munich logo on an oscilloscope screen
main.cpp
- Committer:
- drayde
- Date:
- 2015-06-23
- Revision:
- 0:5276f16d6ac8
File content as of revision 0:5276f16d6ac8:
#include "mbed.h" #include "FastPWM.h" #define min(x,y) ((x > y) ? y : x) #define max(x,y) ((x > y) ? x : y) FastPWM pwmout1(p21); FastPWM pwmout2(p22); DigitalOut gnd(p23); DigitalOut zout(p30); const float waitTime = 0.000005f; const float waitTimeOnOff = waitTime * 5; const uint16_t linesCount = 3; uint16_t lines[3] = { 50, 58, 59 }; const uint16_t count = 50 + 58 + 59; float tline[count*2] = { 48.369133f, 28.8248990f, 48.368286f, 39.8623760f, 48.351325f, 46.3102450f, 48.334335f, 52.7581170f, 49.475196f, 53.4183200f, 50.616059f, 54.0785220f, 53.243757f, 55.5576550f, 54.606233f, 56.1411410f, 57.114615f, 56.6511700f, 59.375927f, 56.5156330f, 60.874326f, 55.9204990f, 62.091060f, 55.0463890f, 63.381650f, 52.9297760f, 64.112835f, 49.9910160f, 64.245790f, 32.3980810f, 64.135779f, 15.2194990f, 61.394651f, 8.323464f, 56.287969f, 3.161953f, 53.549629f, 1.670959f, 50.809912f, 0.864901f, 48.551553f, 0.663871f, 46.319378f, 0.703653f, 46.319384f, 0.703653f, 41.771884f, 1.630293f, 37.661210f, 3.244895f, 25.652307f, 10.270239f, 10.447255f, 19.245676f, 6.857494f, 21.672420f, 4.501644f, 24.214656f, 2.165276f, 28.217320f, 1.003558f, 32.887381f, 0.753147f, 36.341157f, 0.721389f, 42.459346f, 0.739268f, 44.880336f, 0.757146f, 47.301322f, 0.937623f, 46.759876f, 1.118101f, 46.218430f, 2.914027f, 42.413677f, 5.642516f, 39.020793f, 7.916307f, 37.067662f, 12.748684f, 34.2152480f, 22.498228f, 28.6411190f, 32.483871f, 22.8936240f, 36.322240f, 20.7285960f, 38.208913f, 19.9188070f, 41.846881f, 19.3307290f, 44.771649f, 20.3007020f, 46.961058f, 22.6148930f, 48.222403f, 26.0716500f, 48.369133f, 28.8248990f, 31.218976f, 43.621458f, 28.831117f, 44.931821f, 26.009916f, 46.631259f, 23.556446f, 49.026798f, 22.262607f, 51.745174f, 22.384654f, 54.559435f, 24.067583f, 57.178886f, 25.752292f, 58.675306f, 28.113957f, 60.172644f, 40.067016f, 67.088425f, 51.982667f, 74.028337f, 54.866337f, 75.620116f, 56.919580f, 76.396709f, 59.404296f, 76.966447f, 62.191090f, 77.081175f, 64.275877f, 77.036236f, 65.584705f, 76.841860f, 70.340268f, 75.182687f, 74.042962f, 72.548870f, 76.787694f, 68.775052f, 78.626446f, 63.868977f, 79.264536f, 60.552604f, 79.381633f, 56.203943f, 79.252152f, 38.311577f, 79.104273f, 25.613174f, 78.591456f, 22.154913f, 77.214888f, 18.660728f, 76.492625f, 17.328795f, 75.812292f, 16.259090f, 72.476318f, 12.892882f, 67.620877f, 9.627348f, 65.809337f, 8.594852f, 63.213505f, 7.108777f, 60.964386f, 5.831115f, 59.986438f, 5.299696f, 59.980032f, 5.353375f, 60.066736f, 5.482429f, 60.066708f, 5.482429f, 60.306470f, 5.764849f, 60.668044f, 6.187257f, 61.959456f, 7.984005f, 63.130244f, 10.042883f, 63.985197f, 12.073989f, 64.609554f, 14.235729f, 64.757758f, 14.858139f, 64.905961f, 15.480547f, 64.890439f, 23.990692f, 64.874916f, 32.500838f, 64.824032f, 45.300649f, 64.736554f, 50.304271f, 63.087355f, 54.874838f, 59.623785f, 57.154567f, 57.634136f, 57.346340f, 55.508274f, 57.100453f, 51.885523f, 55.531368f, 35.685767f, 46.165152f, 32.571639f, 44.368667f, 31.218976f, 43.621458f, 42.495038f, 36.333182f, 47.729039f, 33.339953f, 47.729039f, 31.792619f, 47.729039f, 30.245284f, 47.625985f, 26.717286f, 47.164493f, 24.643814f, 46.478075f, 23.109990f, 45.520018f, 21.850785f, 43.226395f, 20.277306f, 40.550203f, 20.025078f, 37.608442f, 20.881826f, 32.431660f, 23.694032f, 22.173406f, 29.600607f, 12.539847f, 35.112122f, 8.374712f, 37.564272f, 6.497140f, 39.076506f, 2.228777f, 45.204719f, 1.118711f, 48.737560f, 0.740503f, 52.468628f, 1.260493f, 55.998071f, 2.775410f, 59.505567f, 8.519716f, 65.985043f, 10.531177f, 67.378454f, 15.567997f, 70.274288f, 21.383807f, 73.564774f, 28.254901f, 77.453774f, 39.292928f, 83.643126f, 42.354181f, 84.917021f, 46.105708f, 85.540547f, 49.712607f, 85.446400f, 54.147520f, 84.133871f, 59.058497f, 81.676193f, 60.921011f, 80.589179f, 63.492770f, 79.108980f, 65.646859f, 77.865843f, 66.505190f, 77.348785f, 66.096247f, 77.412454f, 65.203488f, 77.565531f, 62.315773f, 77.788296f, 59.386050f, 77.614347f, 56.239433f, 76.880110f, 53.680922f, 75.794481f, 51.913305f, 74.763871f, 48.616599f, 72.838788f, 38.314969f, 66.847449f, 28.321931f, 61.061033f, 26.512461f, 59.978255f, 25.293782f, 59.179132f, 23.881259f, 57.943434f, 22.714720f, 56.673829f, 22.121329f, 55.670882f, 21.667488f, 54.594427f, 21.527371f, 53.052012f, 21.682559f, 51.350046f, 23.171367f, 48.408091f, 25.935771f, 45.874712f, 29.616191f, 43.719389f, 37.261038f, 39.326411f, 42.495038f, 36.333182f, }; uint16_t line[count*2]; uint16_t xPos, yPos; int32_t offsetx; int32_t offsety; void lineFromTo(int32_t tx1, int32_t ty1, int32_t tx2, int32_t ty2) { int32_t yd = (ty2 - ty1); int32_t xd = (tx2 - tx1); if (abs(xd) > abs(yd)) { int32_t yinc = yd / ((tx2-tx1) >> 16); int32_t y = ty1; uint16_t x = tx1 >> 16; uint16_t x2 = tx2 >> 16; if (xd == 0) return; while (1) { pwmout1.pulsewidth_ticks(x); pwmout2.pulsewidth_ticks((uint16_t)(y >> 16)); wait(waitTime); if (x == x2) break; if (xd > 0) { y += yinc; x++; } else { y -= yinc; x--; } } } else { int32_t xinc = xd / ((ty2-ty1) >> 16); int32_t x = tx1; uint16_t y = ty1 >> 16; uint16_t y2 = ty2 >> 16; if (yd == 0) return; while (1) { pwmout1.pulsewidth_ticks((uint16_t)(x >> 16)); pwmout2.pulsewidth_ticks(y); wait(waitTime); if (y == y2) break; if (yd > 0) { x += xinc; y++; } else { x -= xinc; y--; } } } } void lineWithRotation(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) { // calculate with 32 bits to have the necessary precision int32_t tx1 = x1 << 16; int32_t ty1 = y1 << 16; int32_t tx2 = x2 << 16; int32_t ty2 = y2 << 16; const int32_t horizon = 100; ty1 += (tx1 - (127 << 16)) * offsety / 127 * (y1 - horizon) / 127; ty2 += (tx2 - (127 << 16)) * offsety / 127 * (y2 - horizon) / 127; tx1 = (127 << 16) + (tx1 - (127 << 16)) * offsetx / 127; tx2 = (127 << 16) + (tx2 - (127 << 16)) * offsetx / 127; lineFromTo(tx1, ty1, tx2, ty2); } void setRotation(float rotation) { offsetx = (int32_t)(127 * sin(rotation)); offsety = (int32_t)(30 * cos(rotation)); } void moveTo(uint16_t x, uint16_t y) { lineWithRotation(xPos, yPos, x, y); xPos = x; yPos = y; } int main() { gnd = 0; zout = 1; pwmout1.period_ticks(256); pwmout2.period_ticks(256); /* // test signal while (1) { pwmout1 = 0.5f; pwmout2 = 0.5f; zout = zout ? 0 : 1; } */ float minx = 999999; float maxx = -999999; float miny = 999999; float maxy = -999999; for (uint16_t i = 0; i<count; i++) { float x = tline[i*2]; float y = tline[i*2+1]; minx = min(minx, x); miny = min(miny, y); maxx = max(maxx, x); maxy = max(maxy, y); } float dx = maxx - minx; float dy = maxy - miny; float margin = 8.0f; // do not use full range (needed for perspective correction) float multy = 254.9f - 2 * margin; float offy = 0.01f + margin; float multx = multy; float offx = offy; for (uint16_t i = 0; i<count; i++) { float x = tline[i*2]; float y = tline[i*2+1]; uint16_t xint = (uint16_t)((x - minx) / dx * multx + offx); uint16_t yint = (uint16_t)((y - miny) / dy * multy + offy); line[i*2] = xint; line[i*2+1] = yint; } float rotation = 0; while(1) { setRotation(rotation); rotation += 0.025f; uint16_t pos = 0; for (uint16_t index=0; index<linesCount; index++) { wait(waitTimeOnOff); zout = 1; //off wait(waitTime); moveTo(line[pos*2], line[pos*2+1]); wait(waitTime); zout = 0; // on! wait(waitTimeOnOff); pos++; for (uint16_t i = 1; i<lines[index]; i++,pos++) { moveTo(line[pos*2], line[pos*2+1]); } } } }