#author("2025-05-05T20:08:35+09:00","","")
#author("2025-05-05T20:08:59+09:00","","")
[[Writing-Arduino-Firmware]]

#code(c){{
/*
  Arduino Sketch for the "Wearable LED Matrix Sign", which shows
  a Tweet of Twitter.
            29 April 2015, Takashi Yamanoue @ Fukuyama University. 
*/ [#h191976e]
*/ 
#include <Max3421e.h>
#include <Usb.h>
#include <AndroidAccessory.h>

// Adafruit_NeoMatrix example for single NeoPixel Shield.
// Scrolls 'Howdy' across the matrix in a portrait (vertical) orientation.

#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>
#ifndef PSTR
 #define PSTR // Make Arduino Due happy
#endif

//#include <stdio.h>

#define VWMax 96
#define VHMax 16
#define RWMax 32
#define RHMax 16

#define PIN 6

// MATRIX DECLARATION:
// Parameter 1 = width of NeoPixel matrix
// Parameter 2 = height of matrix
// Parameter 3 = pin number (most are valid)
// Parameter 4 = matrix layout flags, add together as needed:
//   NEO_MATRIX_TOP, NEO_MATRIX_BOTTOM, NEO_MATRIX_LEFT, NEO_MATRIX_RIGHT:
//     Position of the FIRST LED in the matrix; pick two, e.g.
//     NEO_MATRIX_TOP + NEO_MATRIX_LEFT for the top-left corner.
//   NEO_MATRIX_ROWS, NEO_MATRIX_COLUMNS: LEDs are arranged in horizontal
//     rows or in vertical columns, respectively; pick one or the other.
//   NEO_MATRIX_PROGRESSIVE, NEO_MATRIX_ZIGZAG: all rows/columns proceed
//     in the same order, or alternate lines reverse direction; pick one.
//   See example below for these values in action.
// Parameter 5 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)


// Example for NeoPixel Shield.  In this application we'd like to use it
// as a 5x8 tall matrix, with the USB port positioned at the top of the
// Arduino.  When held that way, the first pixel is at the top right, and
// lines are arranged in columns, progressive order.  The shield uses
// 800 KHz (v2) pixels that expect GRB color data.
/* */
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(32, 16, PIN,
  NEO_MATRIX_TOP     + NEO_MATRIX_LEFT +
  NEO_MATRIX_COLUMNS + NEO_MATRIX_ZIGZAG,
  NEO_GRB            + NEO_KHZ800);

const uint16_t colors[] = {
  matrix.Color(255, 0, 0), matrix.Color(0, 255, 0), matrix.Color(0, 0, 255) };
  
uint16_t backGround;
uint16_t virtualGraphicsArea[VWMax][VHMax];
uint16_t realGraphicsArea[RWMax][RHMax];


/*

   Android
   +---------------------+ tweet
       ...
   +---------------------+ tweet max 132 char
     ^        |
     |        | send font at p
    ask       | to arduino and p++, 
    new       | if p>= tweet.length{ 
    font      |   if no next tweet, p=0
    from      |   else renew current tweet by the next and p=0
    arduino   | }
              |
              v
  at the Arduino
      if new font received,
      put the received font at lp, lp++;
      if(lp>=vfmax) lp=0;  
              
   dp (displaying position) = x/8
  
   initial ... x=0, lp=0, dp=0
   
  if lp=dp-1 {
     ask no font
  }
  else{
     ask new font
  }
  
 
                      Android ADK
                         | 'f', [font kind (0 or 1)], f[32]
                         v
                      +-------+
                      | 32byte| or 16 byte
   dp=x/8  char       +-------+
        |                | putFontAt ( char position)
        |                |
        |                | lp ... last received font position
        v                v
+-----------------------------------+ vfmax =VWMax/16
|     virtual matrix                |
|     width: 6x16= 96 dot           |
|     height: 16 dot                |
+-----------------------------------+
        |      |
        |x     |x+31
+-------+      |     copyVirtualPart2Real, x++,
|              |     if x>= VWMax, x=0;
v              v
****************   real matrix [#qb469fde]
**************** ^ [#s2e11f3f]
**************** | [#v54ea8d7]
   ...           16 dot
**************** | [#qaff03fe]
**************** v [#t21d6c43]
**************** [#m2b2d0b0]
**************** [#e08c1f57]
 <--32 dot->

*/ [#e768e45f]

void clearVirtualGraphicsArea(){
  int i,j;
//  printf("start clearVirtualGraphicsArea\n");
    for( i=0;i<VWMax;i++){
      for( j=0;j<VHMax;j++){
          virtualGraphicsArea[i][j]=backGround;
      }
    }
//  printf("end clearVirtualGraphicsArea\n");
}
void clearRealGraphicsArea(){
  int i,j;
//  printf("start clearRealGraphicsArea\n");
    for( i=0;i<RWMax;i++){
      for( j=0;j<RHMax;j++){
          realGraphicsArea[i][j]=backGround;
      }
    }
//  printf("end clearRealGraphicsArea\n");
}
/* */
/* */
void copyVirtualPart2Real(int x){
  
  int i,j,k;
//  printf("start copyVirtualPart2Real\n");
  for( i=0;i<RWMax;i++){
     k=x+i;
     if(k>=VWMax){
         k=(x+i)%VWMax;
     }
     for( j=0;j<RHMax;j++){
         realGraphicsArea[i][j]=virtualGraphicsArea[k][j];
     }
  }
}

void initialVirtualGraphicsArea(){
     int i;
    clearVirtualGraphicsArea();
    for(int c=0;c<10;c++){
        for( i=0;i<RHMax;i++){
           int w=i+c*16;
           if(w<VWMax){
               virtualGraphicsArea[i+c*16][i]=matrix.Color((255-c*16),c*16,c*16);
           }
        }
    }
 
}

void putFontAt(byte f[], int p, uint16_t color){ // font width=8
//   int oneFontSize=8;
//   int w=(oneFontSize+7)/8;
//   Serial.print("pos=");
//   Serial.print(x);
//   Serial.print("\n\r");
//   if(lp>=vfmax) lp=0;
   if(p>=VWMax) return;
   backGround=matrix.Color(0,0,0);   
   for(int i=0;i<VHMax;i++){
	int l=f[i];
	int mask=0x0080;
	for(int k=0;k<8;k++){
	        if((mask & l)!=0){
		    virtualGraphicsArea[k+p*8][i]=color;
//                    Serial.print("*");
                }
		else {
		    virtualGraphicsArea[k+p*8][i]=backGround;
//                    Serial.print(" ");
                }
		mask=mask>>1;
	}
//	Serial.print("\n\r");
   }
//   lp++; 
}
/* */
/*
data format

pin
A0-A7 ... analog input

4-7 ... digital input
8-11 ... digital/analog(pwm) output

receive 
[
  byte cmd[256]; 
]


send
[
  4 (=data_length(byte)),
  'a' 
  port,
  data(high),
  data(low)
]
or
[
  4 (=data_length(byte)),
  'd'
  data  (pin 0-7)
  data  (0x00)
  data  (0x00)
]

*/ [#a3d0a301]
#define analogInMax 8
#define digitalInMax 6
#define digitalOutMax 14
int analogIns[analogInMax];
int digitalIns[digitalInMax];
int digitalOuts[digitalOutMax];
int digitalVal;

AndroidAccessory acc("Google, Inc.",
		     "Twitter2NeoMatrixEx5",
		     "Arduino Board for twitter2neomatrixex5",
		     "1.0",
		     "http://www.android.com",
		     "0000000012345000");
void setup();
void loop();

int realX;
int lp; // last received font position on the virtualGraphicsArea
int dp; // displayed font position on the virtualGraphicsArea
int vfmax; // virtual font area max ... = VWMax/16;
int cRed=255; // color-rgb-r
int cGreen=0; // color-rgb-g
int cBlue=0; // color-rgb-b 
char colorKind='r'; //color kind d:direct, r:rainbow
void setup()
{
   Serial.begin(57600);
   Serial.print("\r\nStart\n\r");
   for(int i=0;i<digitalInMax;i++) digitalIns[i]=i;
   for(int i=0;i<digitalOutMax;i++) digitalOuts[i]=i;

   for(int i=0;i<digitalInMax;i++)
      pinMode(digitalIns[i],INPUT);
   for(int i=digitalInMax+1;i<digitalOutMax;i++)
      pinMode(digitalOuts[i],OUTPUT);
//   pinMode(ledPin, OUTPUT);
//   pinMode(b3Pin, INPUT);
   analogIns[0]=A0;
   analogIns[1]=A1;
   analogIns[2]=A2;
   analogIns[3]=A3;
   analogIns[4]=A4;
   analogIns[5]=A5;
   analogIns[6]=A6;
   analogIns[7]=A7;
   delay(5); // add 2012 12/9
   Serial.print("acc.powerOn Start\n\r");
   acc.powerOn();
   Serial.print("acc.powerOn\n\r");
  matrix.begin();
  matrix.setBrightness(40); 
  backGround=matrix.Color(0,0,0); 
  initialVirtualGraphicsArea();
  /* */
  Serial.print("setup end\n");
  realX=0;
  lp=0;
  dp=0;
  vfmax=VWMax/16;
}

void readAcc(){
  byte inMsg[64];
//     Serial.print("acc is connected\n"); //**
     int len = acc.read(inMsg, sizeof(inMsg), 1);
     int i;
     byte b;
     if(len<=0){
       return;
     }
//     Serial.print("inMsg[0]="); Serial.print(inMsg[0]); Serial.print("\n\r"); //**
     if(inMsg[0]=='a'){
         if(inMsg[1]<digitalOutMax)
            analogWrite(digitalOuts[inMsg[1]], inMsg[2]);
     }
     else
     if(inMsg[0]=='d'){
         if(digitalInMax-1<inMsg[1] && inMsg[1]<digitalOutMax){
             if(inMsg[2]==1)
                digitalWrite(digitalOuts[inMsg[1]], HIGH);
             else
                digitalWrite(digitalOuts[inMsg[1]], LOW);            
         }
     }
       /* */
     else
     if(inMsg[0]=='f'){
         int fontKind=inMsg[1];
         byte font[16];
         if(fontKind==2){ // 16x16 font.
            for(int i=0;i<16;i++){
              font[i]=inMsg[i*2+2];
            }
//          Serial.print("x="); Serial.print(realX); Serial.print("\n\r"); //**
//          Serial.print("lp="); Serial.print(lp); Serial.print("\n\r"); //**
//          Serial.print("dp="); Serial.print(dp); Serial.print("\n\r");  //**
            int fcolor=lp%6;
            if(colorKind=='r')
               putFontAt(font,lp, matrix.Color((255-fcolor*16),fcolor*16,fcolor*16));
            else
               putFontAt(font,lp, matrix.Color(cRed, cGreen, cBlue));
            lp++;
            if(lp>=(VWMax/8)) lp=0;
            for(int i=0;i<16;i++){
              font[i]=inMsg[i*2+3];
            }
//            Serial.print("x="); Serial.print(realX); Serial.print("\n\r"); //*
//            Serial.print("lp="); Serial.print(lp); Serial.print("\n\r"); //*
//            Serial.print("dp="); Serial.print(dp); Serial.print("\n\r"); //*
//            int fcolor=lp%6; 
            if(colorKind=='r')
               putFontAt(font,lp, matrix.Color((255-fcolor*16),fcolor*16,fcolor*16));
            else
               putFontAt(font,lp, matrix.Color(cRed, cGreen, cBlue));
            lp++;            
         }
         else
         if(fontKind==1){ // 8x16 font
             for(int i=0;i<16;i++){
              font[i]=inMsg[i+2];
            }
  //        Serial.print("x="); Serial.print(realX); Serial.print("\n\r");
//          Serial.print("lp="); Serial.print(lp); Serial.print("\n\r");
//          Serial.print("dp="); Serial.print(dp); Serial.print("\n\r"); 
            int fcolor=lp%6;
            if(colorKind=='r')
               putFontAt(font,lp, matrix.Color((255-fcolor*16),fcolor*16,fcolor*16));
            else
               putFontAt(font,lp, matrix.Color(cRed, cGreen, cBlue));
            lp++;          
         }
         if(lp>=(VWMax/8)) lp=0;
     }
     else
     if(inMsg[0]=='c'){ // color inMsg['c','r'|'d',r,g,b]
                          // r: rainbow, d: direct r-g-b
                          // r,g,b... red, green, blue
           colorKind=inMsg[1];
           cRed=inMsg[2];
           cGreen=inMsg[3];
           cBlue=inMsg[4];
//           Serial.print("color-"); Serial.print(colorKind);
//           Serial.print(" red="); Serial.print(cRed);
//           Serial.print(" green="); Serial.print(cGreen);
//           Serial.print(" blue="); Serial.print(cBlue); Serial.print("¥n¥r");
     }
      /* */  
}
void writeAcc(){
  byte outMsg[4];
     digitalVal=0;
     for(int i=0;i<digitalInMax;i++){
       int b=0;
       if(digitalRead(digitalIns[i])==HIGH)
          b=1;
       digitalVal=digitalVal<<1 | b;
     }
     outMsg[0]='d';
     outMsg[1]=digitalVal & 0xff;
     outMsg[2]=0;
     outMsg[3]=0;
     acc.write(outMsg,4);
     /*
     int sensorValue;
     for(int i=0;i<analogInMax;i++){
          sensorValue = analogRead(analogIns[i]);
          outMsg[0]='a';
          outMsg[1]=i;
          outMsg[2]=(sensorValue>>8) & 0xff;
          outMsg[3]=sensorValue & 0xff;
          acc.write(outMsg,4);
     }
     */
   if(realX%8==0){
     if(lp==dp-1){
//       outMsg[0]='f';
//       outMsg[1]='n';
//       outMsg[2]=0;
//       outMsg[3]=0;
//       acc.write(outMsg,4);
     }
     else
     if(lp==dp-2){
     }
     else{
       outMsg[0]='f';
       outMsg[1]='r';
       outMsg[2]=0;
       outMsg[3]=0;
       acc.write(outMsg,4);     
     }
   }  
}

void loop()
{
  byte inMsg[64];
  byte outMsg[4];
  if(realX%4==0){
    if (acc.isConnected()) {
      readAcc();
      writeAcc();
    }
  }
//  Serial.print("neo matrix\n\r");   
  /* */
  matrix.fillScreen(0);
  
  copyVirtualPart2Real(realX);
  for(int i=0;i<RWMax;i++){
     for(int j=0;j<RHMax;j++){
       uint16_t c=realGraphicsArea[i][j];
//       printf("%d\n",c);
       matrix.drawPixel(i,j,c);
     }
  }

  realX++;
  if(realX>=VWMax) realX=0;
  dp=realX/8;
    
  matrix.show();   
  /* */   
   delay(20);
}

}}
----
#counter

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS