Between 3D printing and knitting, I've spent a lot of time working with processes that allow for a high level of customization. It isn't going to take any more effort or cost more money to produce a new custom design or prototype, than if I was creating another piece that I've already made 100 times. The internet is making trends come and go faster than the traditional fashion industry can keep up, and fast fashion is often irresponsible, but there is so much potential to use this technology to instantly create new and custom objects in a sustainable way.

IMG_3757.JPG

 Phase 1: 9to5.tv

As part of 9to5.tv I streamed a project that allowed an online audience to be participants and collaborators, using online tools I developed to design pieces and watch it be knit in real time. 

9to5 is a month-long digital art exhibition in Atlanta that dissolves the boundary between artist and audience by way of an experimental livestream and emerging interfaces. I was thinking about the mediums I use and how they could be influenced in real time by an online audience.

During the stream, there was a collaborative canvas that everyone could draw on together, that resulted in a four-color knit swatch that was 60 by 60 stitches. 

While everyone was working on this canvas I was knitting individually submitted drawings that became pieces of a scarf.

First iterations of the two tools I built for this live stream

This panel is a collective drawing canvas, and potentially going to be a clusterfrick. As you draw anyone else who has this canvas open can see you draw and draw with you. This canvas allows for four colors of yarn and is 180x180 stitches but you can access the other sizes at collectiveknitting.herokuapp.com/?stitches=180 replacing the number of stitches to an increment of 10 between 30 and 180.                                               

This panel is an individual canvas. When you click save it'll send your design to a server for me to download to my knitting machine. If you click save more than once it'll replace your previous submission, but refreshing the page or opening up a new tab allows for a new drawing. To view this window on its own: individualknitting.herokuapp.com/ (the server resets itself after 30 minutes of inactivity so just a warning your submissions will be erased if you draw while I'm not actively download/knitting)

How WebSockets changed my life and the technology I've abandoned for them

I spent a lot of time in 2017 trying to get multiple devices to communicate in my work. Using OpenFrameworks and the OSC library got me close, because I was able to make iPhone apps that could communicate with my Processing sketched running LEDs, but it required the devices to be on the same network. Also asking someone to engage with a public art project enough to actually download an app seemed too much to ask.

But there had to be another way! The internet is doing this every second. How can I do the internet?

The answer that worked for me was WebSockets, a protocol that allows for communication between a user's browser and a server. Watching this four-part video tutorial by Daniel Shiffman was probably one of the most transformative hours of my life.

The tutorial goes through the process of installing Node.js, an environment for executing Javascript code server-side (great if you're already used to writing Javascript with p5.js), writing the code to set up the server, and how to receive data from clients (each user's browser) and send to the other clients. To complete the process code also has to be written on the client-side to connect to the server, send data, and know what to do when it receives data that originates from other users.

Every project will use Websockets differently, and these were a few questions I had in mind when starting to program:

  • What kind of data does my knitting machine want?
  • How to create a canvas that automatically converts the image to this data?
  • How are these drawings being saved and how can they be accessed?
  • How to avoid an individual spamming the feed with multiple entries?

Communicating with the knitting machine

In May I drove up to Pennsylvania on a whim and bought a Passap E6000 knitting machine, and while I haven't had much time to use it recently I absolutely love this machine! Even though these machines were produced in the 90s, it works just like it's new. This is one of the more professional home commerce machines with a lot of stitch types, but I was sold by the ability to use four colors of yarn at once. It comes preloaded with a bunch of patterns, but obviously I was making my own.

I was previously using the software Design-A-Knit to be able to import the images I created in Processing and Photoshop and download them to the machine. I downloaded a serial port monitoring software to read the information that was being sent from DAK to the printer to try to be able to send it with my own apps, and luckily it was so easy to read! It's essentially sending a short message that tells the knitting machine how many colors are in the design, how many stitches wide and tall, and then just going through the whole pattern assigning a value of 0, 1, 2, or 3 for the color of the stitch. It took a few hours of trial and error and the knitting machine screeching at me to get the data exactly as it wanted, but I got it working!

I probably won't use DAK to download patterns anymore, but it still has really great features for creating the shapes of garments and then you can follow along and as you knit it will tell you at what row to increase and decrease your stitches.

IMG_2479a.jpg

Because the knitting machine wants a list of numbers 0-3, I thought it would be easiest to store the data like this from the very beginning. The color of each stitch is saved in a two-dimensional array, and the user's mouse position determines which value in the array is being changed. The code below shows how this array is formatted into the string the knitting machine wants to receive. In the video you can see all the submissions, and when the line breaks are at the right position the image is actually visible!

//section of code that convert drawing data to knitting machine friendly data

var numColors;
var pattern;
     if (maxColors === 2) {
         numColors = 0; //if there are two colors the message begins with 0
     } else {
         numColors = maxColors; //if three or four colors, message begins with that number
     }
//the next set of numbers is the width and height of the pattern, if these numbers are three digits there is one less space between them
     if (w<100) {
  pattern = colorValue+'  '+w+'  '+h+' ';
     } else {
  pattern = colorValue+' '+w+' '+h+' ';
     }
 for (y=0; y<h; y++) { //loop through all rows
   for (x=0; x<w; x++) { //loop through each stitch in that row
   var a= stitches[x][y];  //array that is holding value of 0-3 to determine the color of every stitch in our pattern
   pattern += str(a); //append each stitch to the message 
 }}
       var data = {
           id: ID , // how I determine if someone is submitting over their previous drawing or is a new user 
           stitches: pattern // the message that will saved on the server to be downloaded to the knitting machine
    }
        socket.emit('drawing',data); // send this to the server

The tutorial I mentioned above goes through the process of communicating between the browser through a server, but those messages are not saved and able to be accessed later. This other tutorial by Daniel Shiffman about building an API goes through more server-side programming to actually save the information into a JSON (JavaScript Object Notation) file. To keep the submissions organized and prevent duplicates, the p5.js canvas initializes with an ID value of "0". When the server receives a submission with an ID of "0" it assigns a new ID to the submission, and sends that number back to the user's browser.

It's Digital Knitting but it's still physical work!

knittingloop2.gif
knittingloop.gif
knittingloop3.gif

Phase 2: Making the live feed of submissions public and making it look better

Depending on the number of people that are actively participating in the live stream, it could take a while before you get to see your piece knit as well as the submissions from other people. I added a separate page that allowed for a constantly updating feed that would show the finished collaborate scarf of swatches, as well as a review process in between that would allow for any number of moderators. The first frame below shows an improved drawing tool. Saving your design will only write over your previous drawing so if you'd like to demonstrate multiple submissions open up another tab at http://christmascardknit.herokuapp.com. The second frame shows all submissions that are ready to be reviewed, a green frame around the drawing indicating that it has been approved. The third frame is the final public feed that is continually updated when new drawings are approved. The order is reversed because the scarf is knit from bottom to top.

Questions and Challenges I had when reprogramming:

  • How to allow multiple people to moderate at a time?
    • The submitted designs and whether or not they are approved are both being saved in a JSON file on the server and being broadcasted as WebSockets to every other browser. The JSON loads once when the web page is initially loaded, with the most recent information being shown, but subsequently using WebSockets keeps everyone up to date without having to regularly reload the JSON.
  • How to minimize p5.js redrawing to prevent lagging while drawing and scrolling?
    • use noLoop() to prevent the draw function from being repeated executed and use reDraw() to draw the canvas when the browser receives a websocket, scrolls, or is resized
  • Completely rethinking how elements are drawn because I didn't realize there would be a maximum canvas size...
    • When initially writing the code for the review and public gallery feeds, I was increasing the size of the canvas as new entries came in. When testing I realized the canvas wouldn't draw if over 8000 pixels long, and honestly it made me realize how inefficient that was to begin with. My solution was to crop the canvas to the size of the window, design a scroll bar in the canvas that would offset the position of all the knit swatches, but only draw the swatches that are within the canvas. I had to tinker with it a bit to remap the position of the scroll bar when new submissions were added to let the user know there's more to see, while keeping their position in the feed the same.
 /*
 section of code that draws the public gallery of approved designs
 */

var numSwatch=-1; //start at -1 so first approved swatch is 0

for (index=length; index>0; index--) {  // go backward through submissions because the scarf is knit from bottom to top 

 if (approval[index]=='approved'){ 
      /*
     if a design is approved increase the number of approved
     swatches, using this instead of the index prevents the 
     feed from having holes in it from rejected submissions
      */
         numSwatch++; 
      
  if ((numSwatch+1)*h*s-feedOffset<0) {
    continue; //don't draw this design if above the canvas
        }
  if ((numSwatch-1)*h*s-feedOffset>height) {
    continue; //don't draw this design if below the canvas
        }
   
   // draw all the stiches with the appropriate fill colors
        // w = number of stitches wide
        // h = number of stitches tall
        // s = size of each stitch
     for (x=0; x<w; x++) { 
     for (y=0; y<h; y++) {
       fill(c[stitches[index][x][y]]);  

       beginShape();
        vertex(x*s,y*s+(numSwatch)*h*s-feedOffset); 
        vertex(x*s,y*s+s+(numSwatch)*h*s-feedOffset);
        vertex(x*s+s/2,y*s+s*1.5+(numSwatch)*h*s-feedOffset);
        vertex(x*s+s/2,y*s+s/2+(numSwatch)*h*s-feedOffset);
       endShape(CLOSE);
   
      beginShape();
        vertex(x*s+s,y*s+(numSwatch)*h*s-feedOffset);
        vertex(x*s+s,y*s+s+(numSwatch)*h*s-feedOffset);
        vertex(x*s+s/2,y*s+s*1.5+(numSwatch)*h*s-feedOffset);
        vertex(x*s+s/2,y*s+s/2+(numSwatch)*h*s-feedOffset);
      endShape(CLOSE);
   
        }
        }
  
 }
}

Full video: In the recording, the livestream starts at 57:00. I pull the scarf off the knitting machine at 2:34:00, and spend the following 20 minutes knitting the collaborative canvas piece.