Control multiple MAX7219 with Node.js - node.js

I've been trying to control 4 MAX7219 controlled 8x8 LED arrays, totaling a 8x32 "screen". they are daisy chained, as seen here.
From what I've gathered, I have to send data for all of my arrays; each MAX7219 will process his own data, and the remaining data will "overflow" to the next MAX7219 to process.
This works very nicely when I address only one "row" of my screen: First row getting and displaying the data as intended
The code to achieve it is the following:
write = function(register, data) {
let buf = new Buffer([register, data]);
this.spi.write(buf, (device, buf2) => {
let s = "";
for (let i = 0; i < buf.length; i++)
s = s + buf[i] + " ";
});
}
(from the NPM SPI documentation)
Writing the data:
write(0x01, 0x01);
write(0x01, 0x03);
write(0x01, 0x07);
write(0x01, 0x0F);
The issues start, when I try and write to the second row. Sending the data to the second row messes with the first one, but I just can't wrap my head around to why this happens.
write(0x01, 0x01);
write(0x01, 0x03);
write(0x01, 0x07);
write(0x01, 0x0F);
// Writing to the second row
write(0x02, 0x80);
write(0x02, 0xC0);
write(0x02, 0xE0);
write(0x02, 0xF0);
This results in a second row that looks like it should but a first row that is messed up:
Second row OK, First row messed up
This happens with any combination of rows. The last one is OK, while the previous ones are messed up.
I don't know why other rows get all messed up, when they're not getting written to, beyond the data transfer that is confirmed to be working...
Notes: I'm using a Raspberry Pi Model B+ V1.2 with Raspbian; Node.js v8.11.1;

After studying a few other repositories, (special thanks to bitbank2's great C++ repo), and I've created an NPM Package to do exactly what I wanted it to do:
Control Multiple daisy-chained MAX7219 8x8 LED arrays, in a very simple way.
You can find the Github repository here, and the NPM Package here.

Related

How to power a windowed virtual list with cursor based pagination?

Take a windowed virtual list with the capability of loading an arbitrary range of rows at any point in the list, such as in this following example.
The virtual list provides a callback that is called anytime the user scrolls to some rows that have not been fetched from the backend yet, and provides the start and stop indexes, so that, in an offset based pagination endpoint, I can fetch the required items without fetching any unnecessary data.
const loadMoreItems = (startIndex, stopIndex) => {
fetch(`/items?offset=${startIndex}&limit=${stopIndex - startIndex}`);
}
I'd like to replace my offset based pagination with a cursor based one, but I can't figure out how to reproduce the above logic with it.
The main issue is that I feel like I will need to download all the items before startIndex in order to receive the cursor needed to fetch the items between startIndex and stopIndex.
What's the correct way to approach this?
After some investigation I found what seems to be the way MongoDB approaches the problem:
https://docs.mongodb.com/manual/reference/method/cursor.skip/#mongodb-method-cursor.skip
Obviously he same approach can be adopted by any other backend implementation.
They provide a skip method that allows to skip an arbitrary amount of items after the provided cursor.
This means my sample endpoint would look like the following:
/items?cursor=${cursor}&skip=${skip}&limit=${stopIndex - startIndex}
I then need to figure out the cursor and the skip values.
The following code could work to find the closest available cursor, given I store them together with the items:
// Limit our search only to items before startIndex
const fragment = items.slice(0, startIndex);
// Find the closest cursor index
const cursorIndex = fragment.length - 1 - fragment.reverse().findIndex(item => item.cursor != null);
// Get the cursor
const cursor = items[cursorIndex];
And of course, I also have a way to know the skip value:
const skip = items.length - 1 - cursorIndex;

Typescript Multi Dimensional Array's Values Not Updating (to null)

What I am Doing
I am trying to create a Sudoku solver and generator in Vue. Right now, I have the solving algorithm set up, and just need to generate new problems. I am generating problems by creating a completed Sudoku problem (complete with no bugs), then I have to remove nodes so that there is still only 1 solution to the problem.
The Problem
When I try to access a node from the multi-dimensional array that represents the board, and change it to null (what I am using to display a blank node), the board does not update that value. I am changing it with the following code: newGrid[pos[0]][pos[1]] = null; (where pos[0] is the row, pos[1] is the column , and newGrid is grid we want to mutate). Note that the array is an array with 9 arrays inside, and each of those arrays has 9 numbers (or null) which represent the values for that position in the grid. To elaborate on the bug, if I put a console.log(newGrid), there are normal looking values, and no null.
What I Know and Have Tried
I know it has to do with this specific line, and the fact that I am setting the value equal to null because changing null to another value (i.e. newGrid[pos[0]][pos[1]] = 0;) works and changes the array. The reason I don't just use a value other than null is: null renders and nothing and other values (0) render as something (null nodes should be blank), null is simple to understand in this situation (the logic is node has null, node has nothing, node is blank), and null is already implemented throughout my codebase.
Additionally, if I use console.log(newGrid[pos[0]][pos[1]]), null (the correct output) is outputted, even though console.log(newGrid) shows a number there, not null. Also, oddly enough, this works for one specific node. In row 1 (indexing starts at 0), column 8, null is set. Even though the input (completed) grid is always different, this node is always set to null. Edit: this bug had to do with the input grid already having null here, so it actually doesn't let any nulls be set.
To summarize: I expect an array with a null in a few positions I update, but I get a number instead. Also, there are no errors when the Typescript compiles to Javascript or during runtime.
Code
Given that I am not exactly sure where the problem may be (i.e. maybe I create the array wrong) I am including the minimum code with a pastebin link to the whole file (this is the full code). To restate, the goal of this function is to remove nodes from the list (by replacing them with null) in order to create a Sudoku puzzle with one solution. The code on Stack Overflow only includes some of the whole file, and the pastebin link includes the rest.
//global.d.ts
type Nullable<T> = T | null;
type Grid = Array<Array<number | null>>;
import { Solver } from './Solve';
// Inside the function that does the main work
const rowLen: number = grid.length;
const colLen: number = grid[0].length;
let newGrid: Grid = grid; // Grid is a argument for this function
let fullNodes = GetFirstFull(grid, colLen, rowLen);
let fullNodesLen: number = fullNodes.length;
// Some stuff that figures out how many solutions there are (we only want 1) is excluded
if (solutions != 1) {
fullNodesLen++;
rounds--;
} else {
newGrid[pos[0]][pos[1]] = null;
}
Note that if anything seems confusing check out the pastebin or ask. Thank you so much for taking the time to look at my problem!
Also, it isn't just 0 that works, undefined also makes it set correctly. So, this problem seems to be something with the null keyword...
EDIT:
Given that no one has responded yet, I assume: my problem is a bit hard, there isn't enough information, my post isn't good quality, or not enough people have seen it. To control the problem of not enough information, I would like to include the function that calls this function (just to see if that might be related).
generate(context: ActionContext<State, any>) {
let emptyArray = new Array(9);
for (let i = 0; i < 9; ++i)
emptyArray[i] = [null, null, null, null, null, null, null, null, null];
const fullGrid = Solver(emptyArray);
const puzzle = fullGrid ? Remover(fullGrid, 6) : state.gridLayout;
context.commit('resetBoard', puzzle);
},
Note: If you aren't familiar with Vuex, what context.commit does is changes the state (except it is changing a global state rather than a component state). Given that this function isn't refactored or very easy to read code in the first place, if you have any questions, please ask.
To solve other potential problems: I have been working on this, I have tried a lot of console.log()ing, changing the reference (newGrid) to a deepcopy, moving stuff out of the if statements, verifying code execution, and changing the way the point on the newGrid is set (i.e. by using newgrid.map() with logic to return that point as null). If you have any questions or I can help at all, please ask.

How can I send selected comps in After Effects to AME via extendscript?

I've been trying to figure this out for the past day or two with minimal results. Essentially what I want to do is send my selected comps in After Effects to Adobe Media Encoder via script, and using information about them (substrings of their comp name, width, etc - all of which I already have known and figured out), and specify the appropriate AME preset based on the conditions met. The current two methods that I've found won't work for what I'm trying to do:
https://www.youtube.com/watch?v=K8_KWS3Gs80
https://blogs.adobe.com/creativecloud/new-changed-after-effects-cc-2014/?segment=dva
Both of these options more or less rely on the output module/render queue, (with the first option allowing sending it to AME without specifying preset) which, at least to my knowledge, won't allow h.264 file-types anymore (unless you can somehow trick render queue with a created set of settings prior to pushing queue to AME?).
Another option that I've found involves using BridgeTalk to bypass the output module/render queue and go directly to AME...BUT, that primarily involves specifying a file (rather than the currently selected comps), and requires ONLY having a single comp (to be rendered) at the root level of the project: https://community.adobe.com/t5/after-effects/app-project-renderqueue-queueiname-true/td-p/10551189?page=1
Now as far as code goes, here's the relevant, non-working portion of code:
function render_comps(){
var mySelectedItems = [];
for (var i = 1; i <= app.project.numItems; i++){
if (app.project.item(i).selected)
mySelectedItems[mySelectedItems.length] = app.project.item(i);
}
for (var i = 0; i < mySelectedItems.length; i++){
var mySelection = mySelectedItems[i];
//~ front = app.getFrontend();
//~ front.addItemToBatch(mySelection);
//~ enc = eHost.createEncoderForFormat("H.264");
//~ flag = enc.loadPreset("HD 1080i 25");
//app.getFrontend().addItemToBatch(mySelection);
var bt = new BridgeTalk();
bt.appName = "ame";
bt.target = "ame";
//var message = "alert('Hello')";
//bt.body = message;
bt.body="app.getFrontend().addCompToBatch(mySelection)";
bt.send();
}
}
Which encapsulates a number of different attempts and things that I've tried.
I've spent about 4-5 hours trying to scour the internet and various resources but so far have come up short. Thanks in advance for the help!

MPMoviePlayerContentPreloadDidFinishNotification seems more reliable than MPMoviePlayerLoadStateDidChangeNotification

I am streaming small movies (1-3MB) off my website into my iPhone app. I have a slicehost webserver, I think it's a "500MB slice". Not sure off the top of my head how this translates to bandwidth, but I can figure that out later.
My experience with MPMoviePlayerLoadStateDidChangeNotification is not very good.
I get much more reliable results with the old MPMoviePlayerContentPreloadDidFinishNotification
If I get a MPMoviePlayerContentPreloadDidFinishNotification, the movie will play without stuttering, but if I use MPMoviePlayerLoadStateDidChangeNotification, the movie frequently stalls.
I'm not sure which load state to check for:
enum {
MPMovieLoadStateUnknown = 0,
MPMovieLoadStatePlayable = 1 << 0,
MPMovieLoadStatePlaythroughOK = 1 << 1,
MPMovieLoadStateStalled = 1 << 2,
};
MPMovieLoadStatePlaythroughOK seems to be what I want (based on the description in the documentation):
MPMovieLoadStatePlaythroughOK
Enough data has been buffered for playback to continue uninterrupted.
Available in iOS 3.2 and later.
but that load state NEVER gets set to this in my app.
Am I missing something? Is there a better way to do this?
Just making sure that you noticed it's a flag, not a value?
MPMoviePlayerController *mp = [aNotification object];
NSLog(#"LoadState: %i", (NSInteger)mp.loadState);
if (mp.loadState & MPMovieLoadStatePlaythroughOK)
{
// Do stuff
}

Parallel.ForEach Ordered Execution

I am trying to execute parallel functions on a list of objects using the new C# 4.0 Parallel.ForEach function. This is a very long maintenance process. I would like to make it execute in the order of the list so that I can stop and continue execution at the previous point. How do I do this?
Here is an example. I have a list of objects: a1 to a100. This is the current order:
a1, a51, a2, a52, a3, a53...
I want this order:
a1, a2, a3, a4...
I am OK with some objects being run out of order, but as long as I can find a point in the list where I can say that all objects before this point were run. I read the parallel programming csharp whitepaper and didn't see anything about it. There isn't a setting for this in the ParallelOptions class.
Do something like this:
int current = 0;
object lockCurrent = new object();
Parallel.For(0, list.Count,
new ParallelOptions { MaxDegreeOfParallelism = MaxThreads },
(ii, loopState) => {
// So the way Parallel.For works is that it chunks the task list up with each thread getting a chunk to work on...
// e.g. [1-1,000], [1,001- 2,000], [2,001-3,000] etc...
// We have prioritized our job queue such that more important tasks come first. So we don't want the task list to be
// broken up, we want the task list to be run in roughly the same order we started with. So we ignore tha past in
// loop variable and just increment our own counter.
int thisCurrent = 0;
lock (lockCurrent) {
thisCurrent = current;
current++;
}
dothework(list[thisCurrent]);
});
You can see how when you break out of the parallel for loop you will know the last list item to be executed, assuming you let all threads finish prior to breaking. I'm not a big fan of PLINQ or LINQ. I honestly don't see how writing LINQ/PLINQ leads to maintainable source code or readability.... Parallel.For is a much better solution.
If you use Parallel.Break to terminate the loop then you are guarenteed that all indices below the returned value will have been executed. This is about as close as you can get. The example here uses For but ForEach has similar overloads.
int n = ...
var result = new double[n];
var loopResult = Parallel.For(0, n, (i, loopState) =>
{
if (/* break condition is true */)
{
loopState.Break();
return;
}
result[i] = DoWork(i);
});
if (!loopResult.IsCompleted &&
loopResult.LowestBreakIteration.HasValue)
{
Console.WriteLine("Loop encountered a break at {0}",
loopResult.LowestBreakIteration.Value);
}
In a ForEach loop, an iteration index is generated internally for each element in each partition. Execution takes place out of order but after break you know that all the iterations lower than LowestBreakIteration will have been completed.
Taken from "Parallel Programming with Microsoft .NET" http://parallelpatterns.codeplex.com/
Available on MSDN. See http://msdn.microsoft.com/en-us/library/ff963552.aspx. The section "Breaking out of loops early" covers this scenario.
See also: http://msdn.microsoft.com/en-us/library/dd460721.aspx
For anyone else who comes across this question - if you're looping over an array or list (rather than an IEnumberable ), you can use the overload of Parallel.Foreach that gives the element index to maintain original order too.
string[] MyArray; // array of stuff to do parallel tasks on
string[] ProcessedArray = new string[MyArray.Length];
Parallel.ForEach(MyArray, (ArrayItem,loopstate,ArrayElementIndex) =>
{
string ProcessedArrayItem = TaskToDo(ArrayItem);
ProcessedArray[ArrayElementIndex] = ProcessedArrayItem;
});
As an alternate suggestion, you could record which object have been run and then filter the list when you resume exection to exclude the objects which have already run.
If this needs to be persistent across application restarts, you can store the ID's of the already executed objects (I assume here the objects have some unique identifier).
For anybody looking for a simple solution, I have posted 2 extension methods (one using PLINQ and one using Parallel.ForEach) as part of an answer to the following question:
Ordered PLINQ ForAll
Not sure if question was altered as my comment seems wrong.
Here improved, basically remind that parallel jobs run in out of your control order.
ea printing 10 numbers might result in 1,4,6,7,2,3,9,0.
If you like to stop your program and continue later.
Problems alike this usually endup in batching workloads.
And have some logging of what was done.
Say if you had to check 10.000 numbers for prime or so.
You could loop in batches of size 100, and have a prime log1, log2, log3
log1= 0..99
log2=100..199
Be sure to set some marker to know if a batch job was finished.
Its a general aprouch since the question isnt that exact either.

Resources