Function not looping properly for Arduino with NeoPixels - c++

I'm animating/lighting a sign using an Arduino + NeoPixels for Halloween at my place of work. One of my two functions (a slow, spreading, red glow) works fine. The other - a slowing heartbeat - never slows down and seems stuck in an infinite loop.
Here's the full, relevant code:
void loop() {
// HeartBeat Test
for(int bpm=60;bpm >= 0;bpm=bpm-3) {
systolicUp(bpm);
systolicDown(bpm);
diastolicUp(bpm);
diastolicDown(bpm);
restBeat(bpm);
}
}
void systolicUp(int i) {
uint16_t beatSeconds, firstPulse, firstIncrement, j, k;
beatSeconds = 60000/i;
firstPulse = beatSeconds * 0.6;
firstIncrement = firstPulse/170;
for(j=0; j <= 255; j=j+3) {
uint32_t redShade = strip.Color(j, 0, 0);
for (k=0; k<strip.numPixels(); k++) {
strip.setPixelColor(k, redShade);
}
strip.show();
delay(firstIncrement);
}
}
void systolicDown(int i) {
uint16_t beatSeconds, firstPulse, firstIncrement, j, k;
beatSeconds = 60000/i;
firstPulse = beatSeconds * 0.6;
firstIncrement = firstPulse/170;
for(j=255; j >= 0; j=j-3) {
uint32_t redShade = strip.Color(j, 0, 0);
for (k=0; k<strip.numPixels(); k++) {
strip.setPixelColor(k, redShade);
}
strip.show();
delay(firstIncrement);
}
}
void diastolicUp(int i) {
uint16_t beatSeconds, secondPulse, secondIncrement, j, k;
beatSeconds = 60000/i;
secondPulse = beatSeconds * 0.3;
secondIncrement = secondPulse/170;
for(j=0; j <= 255; j=j+3) {
uint32_t redShade = strip.Color(j, 0, 0);
for (k=0; k<strip.numPixels(); k++) {
strip.setPixelColor(k, redShade);
}
strip.show();
delay(secondIncrement);
}
}
void diastolicDown(int i) {
beatSeconds = 60000/i;
uint16_t beatSeconds, secondPulse, secondIncrement, j, k;
secondPulse = beatSeconds * 0.3;
secondIncrement = secondPulse/170;
for(j=255; j >= 0; j=j-3) {
uint32_t redShade = strip.Color(j, 0, 0);
for (k=0; k<strip.numPixels(); k++) {
strip.setPixelColor(k, redShade);
}
strip.show();
delay(secondIncrement);
}
}
void restBeat(int i) {
uint16_t beatSeconds, rest, g;
beatSeconds = 60000/i;
rest = beatSeconds * 0.1;
for (g=0; g<strip.numPixels(); g++) {
strip.setPixelColor(g, 0, 0, 0);
}
strip.show();
delay(rest);
}
By the math, I should be handing over a certain number of beats-per-minute, the number of seconds-per-beat is calculated, the light pulses once over 60% of that, pulses again over 30%, and then is silent for 10%. This should happen 20 times, with each beat getting slower progressively until it stops completely.
Instead, I'm getting steady once-per-second blinking.
I'm certain it'll end up being something that I've totally overlooked, or missed in the NeoPixel documentation. But, as I'm either overlooking or have totally missed it, help would be appreciated. :)

void diastolicDown(int i) {
beatSeconds = 60000/i;
uint16_t beatSeconds, secondPulse, secondIncrement, j, k;
Here you're trying to assign a value to beatSeconds before its declaration.

Related

Non-blocking theater style chase animation for NeoPixels

I am trying to adapt this version of the Adafruit NeoPixel theater chase example to be non-blocking by not using the delay() function and instead of using the millis() function to create a counter, however, I am having no luck as the NeoPixels just light up constantly. Am I missing something? I decided to place the if statement at the point where the nested for loop turns off every 3rd pixel in the strand thinking this would be the spot to put it since in the old code the delay() was called previous to this step.
Here is this version I made which doesn't work:
//Theatre-style crawling lights.
void theaterChase(uint32_t c, const long wait) {
unsigned long currentMillis = millis();
for (int j = 0; j < 10; j++) { //do 10 cycles of chasing
for (int q = 0; q < 3; q++) {
for (uint16_t i = 0; i < strip.numPixels(); i = i + 3) {
strip.setPixelColor(i + q, c); //turn every third pixel on
}
strip.show();
if (currentMillis - previousMillis >= wait) {
previousMillis = currentMillis;
for (uint16_t i = 0; i < strip.numPixels(); i = i + 3) {
strip.setPixelColor(i + q, 0); //turn every third pixel off
}
}
}
}
}
and here is the old version:
//Theatre-style crawling lights.
void theaterChase(uint32_t c, uint8_t wait) {
for (int j=0; j<10; j++) { //do 10 cycles of chasing
for (int q=0; q < 3; q++) {
for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, c); //turn every third pixel on
}
strip.show();
delay(wait);
for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, 0); //turn every third pixel off
}
}
}
}
The for loops wrapped around the delay are what does the blocking.
You have to disassemble the nested for loops that are wrapped around delay() into their constituent parts.
You can turn the for(j...){} loop into the if( currentMillis -last > wait){} conditional and rely on the outer loop() to call this function frequently.
You make q save state with a static and do the iteration arithmetic yourself
Untested code:
//Theatre-style crawling lights.
void theaterChase(uint32_t c, const long wait) {
static unsigned long last;
static int q;
unsigned long currentMillis = millis();
if( currentMillis -last > wait){
last = currentMillis;
if(q >= 3) q = 0;
if(q < 3){
for (uint16_t i = 0; i < strip.numPixels(); i = i + 3) {
strip.setPixelColor(i + q, c); //turn every third pixel on
}
strip.show();
// setup to turn them back off during the next iteration
for (uint16_t i = 0; i < strip.numPixels(); i = i + 3) {
strip.setPixelColor(i + q, 0); //turn every third pixel off
}
q++;
}// if(q ...
} // if( currentMillis...
}

Corrupted memory issue when deleting allocated memory

I am trying to store a sparse vector using a bit mask. I allocate a char* to represent the bit mask. However, when I delete [] the mask, I get a memory corruption error. Upon investigation, I'm seeing that it's because I'm freeing memory that I'm not supposed to. This is confusing, since I don't see how this could be the case.
When I run this on my case, it prints out "ALLOCATED" and "DEALLOCATING" but nothing further.
void set_i_bit(char* mask, int i) {
int field_num = floor(i/8);
int bit_num = i %8;
mask[field_num] = (1 << bit_num) | mask[field_num];
}
int write_sparse_with_bitmask(vector<float> arr, ofstream* fout) {
int mx_sz = arr.size() - 1;
float tol = 0.5;
char* mask = 0;
for(int i = arr.size() -1; i>=0; i-=1) {
if (fabs(arr[i]) > tol) break;
mx_sz = i;
}
int sprse_cnt = 0;
for(int i = 0; i<=mx_sz; i+=1) {
if (fabs(arr[i]) < tol) sprse_cnt++;
}
int bitmask_sz = ceil(mx_sz/8);
if (sprse_cnt*sizeof(int16_t) + sizeof(int16_t) > bitmask_sz) {
cout<<"ALLOCATED"<<endl;
mask = new char[bitmask_sz];
for (int i =0; i<bitmask_sz; i++) mask[i] = 0;
for(int i = 0; i<=mx_sz; i+=1) {
if (fabs(arr[i]) > coef_tol) {
set_i_bit(mask, i);
}
}
}
else {
bitmask_sz = 0;
}
uint16_t sz = mx_sz + 1;
uint16_t bt_msk = bitmask_sz + 1;
char flag = 0;
if (bitmask_sz > 0) {
flag = flag | 1;
}
fout->write((char*)&sz, sizeof(uint16_t));
fout->write((char*)&flag, sizeof(char));
int w_size = sizeof(uint16_t) + sizeof(char);
if (flag & 1) {
fout->write((char*)&bt_msk, sizeof(uint16_t));
fout->write(mask, sizeof(char)*bt_msk);
cout<<"DEALLOCATING"<<endl;
delete [] mask;
cout<<"THIS DOESN'T PRINT"<<endl;
w_size += sizeof(uint16_t) + sizeof(char)*bt_msk;
}
for(int i = 0; i<=mx_sz; i+=1) {
if (fabs(arr[i]) > tol || !(flag & 1)) {
int16_t vl = arr[i];
fout->write((char*) &vl, sizeof(int16_t));
w_size += sizeof(int16_t);
}
}
return w_size;
}

Implementing rasterization and depth buffer in c++

I am trying to implement the rasterization method in cc+. I am trying to implement an interpolation function that handles the interpolation between the x,y and z vertices. That way I can save the inverse of z in a depth buffer.
At this point I get only the vertices drawn on the rendered image. Can someone see what is wrong with my code? I have posted the full code so you can see the whole program.
Many thanks in advance.
EDIT
I saw that I had made an error in vertexshader by writing pixel.zinv = 1 / vPrime.z instead of p.zinv = 1/ vPrime.z. Now nothing renders, just a black screen.
EDIT 2
My check to see if a pixel should be painted was wrong.
if (depthBuffer[row[i].x][row[i].y] < row[i].zinv)
is correct. Now I get little pieces of color.
#include <iostream>
#include <glm/glm.hpp>
#include <SDL.h>
#include "SDLauxiliary.h"
#include "TestModel.h"
using namespace std;
using glm::vec2;
using glm::vec3;
using glm::ivec2;
using glm::mat3;
using glm::max;
// ----------------------------------------------------------------------------
// GLOBAL VARIABLES
int cc = 0;
const int SCREEN_WIDTH = 500;
const int SCREEN_HEIGHT = 500;
SDL_Surface* screen;
int t;
vector<Triangle> triangles;
vec3 cameraPos(0, 0, -3.001);
float f = 500;
double yaw = 0;
vec3 c1(cos(yaw), 0, -sin(yaw));
vec3 c2(0, 1, 0);
vec3 c3(sin(yaw), 0, cos(yaw));
glm::mat3 R(c1, c2, c3);
float translation = 0.1; // use this to set translation increment
const float PI = 3.1415927;
vec3 currentColor;
float depthBuffer[SCREEN_HEIGHT][SCREEN_WIDTH];
// ----------------------------------------------------------------------------
// STUCTURES
struct Pixel
{
int x;
int y;
float zinv;
}pixel;
// ----------------------------------------------------------------------------
// FUNCTIONS
void Update();
void Draw();
void VertexShader(const vec3& v, Pixel& p);
void Interpolate(ivec2 a, ivec2 b, vector<ivec2>& result);
void DrawLineSDL(SDL_Surface* surface, ivec2 a, ivec2 b, vec3 color);
void DrawPolygonEdges(const vector<vec3>& vertices);
void ComputePolygonRows(const vector<Pixel>& vertexPixels, vector<Pixel>& leftPixels, vector<Pixel>& rightPixels);
void DrawPolygonRows(const vector<Pixel>& leftPixels, const vector<Pixel>& rightPixels);
void DrawPolygon(const vector<vec3>& vertices);
void Interpolate2(Pixel a, Pixel b, vector<Pixel>& result);
int main(int argc, char* argv[])
{
LoadTestModel(triangles);
screen = InitializeSDL(SCREEN_WIDTH, SCREEN_HEIGHT);
t = SDL_GetTicks(); // Set start value for timer.
while (NoQuitMessageSDL())
{
Draw();
}
//Draw();
//cin.get();
SDL_SaveBMP(screen, "screenshot.bmp");
return 0;
}
void Draw()
{
SDL_FillRect(screen, 0, 0);
if (SDL_MUSTLOCK(screen))
SDL_LockSurface(screen);
for (int y = 0; y<SCREEN_HEIGHT; ++y)
for (int x = 0; x<SCREEN_WIDTH; ++x)
depthBuffer[y][x] = 0;
for (int i = 0; i<triangles.size(); ++i)
{
currentColor = triangles[i].color;
vector<vec3> vertices(3);
int aa = 24;
vertices[0] = triangles[i].v0;
vertices[1] = triangles[i].v1;
vertices[2] = triangles[i].v2;
DrawPolygon(vertices);
}
if (SDL_MUSTLOCK(screen))
SDL_UnlockSurface(screen);
SDL_UpdateRect(screen, 0, 0, 0, 0);
}
void VertexShader(const vec3& v, Pixel& p)
{
vec3 vPrime = (v - cameraPos)*R;
p.zinv = 1 / vPrime.z;
p.x = f * vPrime.x / vPrime.z + SCREEN_WIDTH / 2;
p.y = f * vPrime.y / vPrime.z + SCREEN_HEIGHT / 2;
//cout << p.x << " this is it " << p.y << endl;
depthBuffer[p.x][p.y] = pixel.zinv;
}
void ComputePolygonRows(const vector<Pixel>& vertexPixels,
vector<Pixel>& leftPixels, vector<Pixel>& rightPixels)
{
// Find y-min,max for the 3 vertices
vec3 vp(vertexPixels[0].y, vertexPixels[1].y, vertexPixels[2].y);
Pixel start; Pixel end; Pixel middle;
int yMin = 1000;
int yMax = -1000;
int w=0; int s=0;
for (int k = 0; k < vertexPixels.size(); ++k)
{
if (vp[k] <= yMin)
{
yMin = vp[k];
end = vertexPixels[k];
w = k;
}
}
for (int k = 0; k < vertexPixels.size(); ++k)
{
if (vp[k] >= yMax)
{
yMax = vp[k];
start = vertexPixels[k];
s = k;
}
}
for (int k = 0; k < vertexPixels.size(); ++k)
{
if (vertexPixels[k].y != start.y
&& vertexPixels[k].y != end.y)
{
middle = vertexPixels[k];
}
if (w!= k && s!= k)
{
middle = vertexPixels[k];
}
}
int ROWS = yMax - yMin + 1;
leftPixels.resize(ROWS);
rightPixels.resize(ROWS);
for (int i = 0; i<ROWS; ++i)
{
leftPixels[i].x = +numeric_limits<int>::max();
rightPixels[i].x = -numeric_limits<int>::max();
}
int pixels1 = glm::abs(start.y - end.y) + 1;
vector<Pixel> line1(pixels1);
Interpolate2(end, start, line1);
int pixels2 = glm::abs(end.y - middle.y) + 1;
vector<Pixel> line2(pixels2);
Interpolate2(end, middle, line2);
int pixels3 = glm::abs(middle.y - start.y) + 1;
vector<Pixel> line3(pixels3);
Interpolate2(middle, start, line3);
vector<Pixel> side1(ROWS);
for (int i = 0; i < line2.size(); ++i)
{
side1[i] = line2[i];
}
for (int i = 0; i < line3.size(); ++i)
{
side1[line2.size()+i-1] = line3[i];
}
for (int i = 0; i < ROWS; ++i)
{
if (line1[i].x < leftPixels[i].x)
{
leftPixels[i] = line1[i];
}
if (line1[i].x > rightPixels[i].x)
{
rightPixels[i] = line1[i];
}
if (side1[i].x < leftPixels[i].x)
{
leftPixels[i] = side1[i];
}
if (side1[i].x > rightPixels[i].x)
{
rightPixels[i] = side1[i];
}
}
}
void DrawPolygonRows(const vector<Pixel>& leftPixels, const vector<Pixel>& rightPixels)
{
//cout << cc++ << endl;
for (int k = 0; k < leftPixels.size(); ++k)
{
int pixels = glm::abs(leftPixels[k].x - rightPixels[k].x) + 1;
vector<Pixel> row(pixels);
Interpolate2(leftPixels[k], rightPixels[k], row);
for (int i = 0; i < pixels; ++i)
{
if (depthBuffer[row[i].x][row[i].y] < row[i].zinv)
{
PutPixelSDL(screen, row[i].x, row[i].y, currentColor);
depthBuffer[row[i].x][row[i].y] = row[i].zinv;
}
}
}
}
void DrawPolygon(const vector<vec3>& vertices)
{
int V = vertices.size();
vector<Pixel> vertexPixels(V);
for (int i = 0; i<V; ++i)
VertexShader(vertices[i], vertexPixels[i]);
vector<Pixel> leftPixels;
vector<Pixel> rightPixels;
ComputePolygonRows(vertexPixels, leftPixels, rightPixels);
DrawPolygonRows(leftPixels, rightPixels);
}
void Interpolate2(Pixel a, Pixel b, vector<Pixel>& result)
{
int N = result.size();
float stepx = (b.x - a.x) / float(glm::max(N - 1, 1));
float stepy = (b.y - a.y) / float(glm::max(N - 1, 1));
float stepz = (b.zinv - a.zinv) / float(glm::max(N - 1, 1));
float currentx = a.x;
float currenty = a.y;
float currentz = a.zinv;
for (int i = 0; i<N; ++i)
{
result[i].x = currentx;
result[i].y = currenty;
result[i].zinv = currentz;
currentx = a.x;
currenty = a.y;
currentz = a.zinv;
currentx += stepx;
currenty += stepy;
currentz += stepz;
}
}
The last loop in the last function seems incorrect to me. You define currentx outside the loop. Then, define a local variable inside the loop with the same name and use it later in the loop. I'd suggest not using the same name for variable inside the loop and outside it to make it more readable. Also, using global variables make the code difficult to read too, since I prefer to look at a function as a separate entity for analysis.

CUDA SHA-Calculation fails [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I want to write a SHA1-Function in CUDA, but when I execute the function, I get wrong results out of the function. When I run the same function on the CPU, I get correct results. My SHA-Function looks like:
__device__ void SHA1_CUDA(uint8_t input_string[], int slen, uint32_t Hash_ptr[])
{
printf("Input string is %s, input len is %d\n", input_string, slen);
uint32_t K[80];
uint32_t A,B,C,D,E,TEMP;
int r,k,ln,t,l,i,j;
Hash_ptr[0]=0x67452301;
Hash_ptr[1]=0xefcdab89;
Hash_ptr[2]=0x98badcfe;
Hash_ptr[3]=0x10325476;
Hash_ptr[4]=0xc3d2e1f0;
ln=slen;
r = (int)((ln+1)/64);
if (((ln+1) % 64) > 56)
{
r=r+1;
}
// initialize Constants
for(t=0; t<80; t++)
{
if (t<20)
{
K[t] = 0x5a827999;
}
if ((t>19)&(t<40))
{
K[t] = 0x6ED9EBA1;
}
if ((t>39)&(t<60))
{
K[t] = 0x8F1BBCDC;
}
if (t>59)
{
K[t] = 0xca62c1d6;
}
}
for(l=0; l <= r; l++)
{
uint32_t W[80]={0};
//Initialize Text
for (i=0; i<16; i++)
{
for(j=0; j<4; j++)
{
if (4*i+j <= ln)
{
k = input_string[64*l+4*i+j];
}
else
{
k =0;
}
if (k<0)
{
k = k +256;
}
if (4*i+j == ln)
{
k = 0x80;
}
// W[i]= W[i] + k*(uint32_t)pow(256,(double)3-j);
W[i]= W[i] + k*expo_d[3-j];
}
}
if ((W[14]==0)&(W[15]==0))
{
W[15]=8*slen;
}
// Hash Cycle
for (t = 16; t <80; t++)
{
W[t] = Rol(W[t-3]^W[t-8]^W[t-14]^W[t-16],1);
}
A = Hash_ptr[0];
B = Hash_ptr[1];
C = Hash_ptr[2];
D = Hash_ptr[3];
E = Hash_ptr[4];
for(t = 0; t < 80; t++)
{
TEMP = (Rol(A,5) + f(B,C,D,t) + E + W[t] + K[t]);
E = D;
D = C;
C = Rol(B,30);
B = A;
A = TEMP;
}
Hash_ptr[0] = Hash_ptr[0] + A;
Hash_ptr[1] = Hash_ptr[1] + B;
Hash_ptr[2] = Hash_ptr[2] + C;
Hash_ptr[3] = Hash_ptr[3] + D;
Hash_ptr[4] = Hash_ptr[4] + E;
ln = ln - 64;
}
}
(host function is analogous, only with __host__ instead of __device__).
My kernel function is
__global__ void test_sha(uint8_t pw[], int* pw_len, uint32_t H[])
{
SHA1_CUDA(pw, *pw_len, H);
}
and I'm calling it like
printf("\nTesting SHA\n");
uint32_t * H_h = (uint32_t*)malloc(sizeof(uint32_t)*5);
memset(H_h, 0, sizeof(uint32_t) * 5);
uint32_t * H_d;
cudaMalloc(&H_d, sizeof(uint32_t)*5);
cudaMemcpy(H_d, H_h, 5*sizeof(uint32_t), cudaMemcpyHostToDevice);
test_sha<<<1, 1>>>(Pass_d, Pass_len_d, H_d);
cudaMemcpy(H_h, H_d, 5*sizeof(uint32_t), cudaMemcpyDeviceToHost);
cudaFree(H_d);
for(int i = 0; i < 5; i++)
printf("%x ", H_h[i]);
printf("\n\n");
printf("Comparing to CPU: \n");
SHA1_CUDA_h(Pass_h, Pass_len, H_h);
for(int i = 0; i < 5; i++)
printf("%x ", H_h[i]);
printf("\n\n");
free(H_h);
So, my printf-function in the SHA-function tells me that everything has been transferred correctly, but nevertheless I get wrong results...
Where is my mistake?
Problem solved, the ROL-function Rol_CUDA I was using in my function returned bad values, thus no one except me could solve the problem.
For everyone who wants to use this function: In line 51 on pastebin, there should be a 32-y, and not a -y. With this correction everything works.

Generating a histogram

I have a problem in generating a histogram. I have got a set of data which i want to be counted and stored in a file in order to make in excel a diagram, just like an image histogram.
Here is my code but I get the right number of data in total, but not the frequency how often. I have set the width of the histogram to 0.01 thats only a test later I have to improve it.
void TPictureWindow::Histogramm()
{
unsigned long retval;
char buffer[100];
int valueHist[260];
int finalVal;
double value = 0.0;
double histWidth = 0.01;
int counter = 0;
scaling = 0.005078125;
HANDLE hDataFile = CreateFile("Histogramm.txt", GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
for(int i = 0; i < NumImages; i++)
{
for(int j = 0; j < edge[i][0]->total; j++)
{
for(int k = 0;k < sizeof(valueHist);k++){
CvPoint* pt1 = CV_GET_SEQ_ELEM(CvPoint, edge[i][0], j);
CvPoint* pt2 = CV_GET_SEQ_ELEM(CvPoint, edge[i][1], j);
value = (pt1->y-pt2->y)*scaling;
if(value < 0) value = 0.0;
finalVal = value/histWidth;
//sprintf(buffer, "final: %d\nvalue: %f\n", finalVal, value);
//MessageBox(buffer, "", MB_OK);
if(finalVal == k){
counter++;
valueHist[k] = counter;
sprintf(buffer, "%9.3d\n", valueHist[k]);
WriteFile(hDataFile, buffer, strlen(buffer), &retval, NULL);
}
}
}
}
CloseHandle(hDataFile);
PostMessage(READY_WITH, IMG_3D_PROFILE, 0);
}
Use the value to calculate its bin instead of searching for the bin should be both easier and faster.
for(int i = 0; i < NumImages; i++) {
for(int j = 0; j < edge[i][0]->total; j++) {
CvPoint* pt1 = CV_GET_SEQ_ELEM(CvPoint, edge[i][0], j);
CvPoint* pt2 = CV_GET_SEQ_ELEM(CvPoint, edge[i][1], j);
int bin
value = (pt1->y-pt2->y)*scaling;
if(value < 0) value = 0.0;
int bin = floor(value/binSize);
if ( bin < maxBin ) {
hist[bin] = hist[bin] + 1;
} else {
/* Report a lost point if interested */
}
}
}
You will loose points if maxBin * binSize < max(value).