Zac
Zac

Reputation: 2279

Java: Unsigned byte creation by bit-wise AND

I would like to create a bit array which will be sent via serial RS232 to an Arduino to control output pins.

I'm doing this by creating checkboxes which when selected send a byte which each bit referring to a pin (on or off).

I have implemented the code for the first 8 checkboxes using a bit-wise AND operation and a print to system out to confirm I'm getting the correct bit pattern.

It works for the first 7 checkboxes but the 8th doesn't work because java byte is signed and won't allow me to assign '255' to the byte value. Is there a way around this?

The important code is this bit :

    private void createOutputChars(){
    byte outputByte1 = 0;
    byte testByte = 1;
    for (int x = 0;x < 8;x++){
        if (digitalPinOutputArray[x].isSelected()) {
           outputByte1 += (byte) (testByte);
        }
        testByte = (byte) (testByte << 1);
    }

    printByteArray(outputByte1);

}


private void printByteArray(int inputByte) {
    // print out 1 or 0
    byte comparison = 0x1;
    for (int x = 0;x < 8;x++)
    {
        if ((inputByte & comparison) > 0) {
            System.out.print("1");
        }
        else {System.out.print("0");}
        comparison = (byte) (comparison << 1);
    }
    System.out.println();
}

The full compilable Java code is this :

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package my.ArduinoGUI;


import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class ArduinoGUI extends javax.swing.JFrame {

/**
 * Creates new form ArduinoGUI
 */
public ArduinoGUI() {
    initCustomComponents();
    initComponents();

}

/**
 * This method is called from within the constructor to initialize the form.
 * WARNING: Do NOT modify this code. The content of this method is always
 * regenerated by the Form Editor.
 */
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {

    buttonGroup1 = new javax.swing.ButtonGroup();
    jPanel1 = new javax.swing.JPanel();
    digitalPinPanel = new javax.swing.JPanel(new GridLayout(0, 3));
    jPanel3 = new javax.swing.JPanel(new GridLayout(0, 1));
    jPanel2 = new javax.swing.JPanel();
    jProgressBar1 = new javax.swing.JProgressBar();
    jProgressBar2 = new javax.swing.JProgressBar();
    jProgressBar3 = new javax.swing.JProgressBar();
    jProgressBar4 = new javax.swing.JProgressBar();
    jProgressBar5 = new javax.swing.JProgressBar();
    jProgressBar6 = new javax.swing.JProgressBar();
    jLabel1 = new javax.swing.JLabel();
    jLabel2 = new javax.swing.JLabel();
    jLabel3 = new javax.swing.JLabel();
    jLabel4 = new javax.swing.JLabel();
    jLabel5 = new javax.swing.JLabel();
    jLabel6 = new javax.swing.JLabel();
    jLabel7 = new javax.swing.JLabel();
    jLabel8 = new javax.swing.JLabel();
    jProgressBar7 = new javax.swing.JProgressBar();
    jProgressBar8 = new javax.swing.JProgressBar();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

    jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Outputs"));
    jPanel1.setName("Outputs"); // NOI18N

    javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
    jPanel1.setLayout(jPanel1Layout);
    jPanel1Layout.setHorizontalGroup(
        jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGap(0, 209, Short.MAX_VALUE)
    );
    jPanel1Layout.setVerticalGroup(
        jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGap(0, 106, Short.MAX_VALUE)
    );

    digitalPinPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Digital Pin State"));
    digitalPinPanel.addMouseListener(new java.awt.event.MouseAdapter() {
        public void mouseReleased(java.awt.event.MouseEvent evt) {
            digitalPinPanelMouseReleased(evt);
        }
    });
    digitalPinLabelArray = new javax.swing.JLabel[digitalPinTotal];
    digitalPinRadioButtonArray = new javax.swing.JRadioButton[digitalPinTotal][2];
    digitalPinGroupArray = new javax.swing.ButtonGroup[digitalPinTotal];
    for(int x = 0; x < digitalPinTotal ; x++) {
        digitalPinGroupArray[x] = new javax.swing.ButtonGroup(); // populate button group
        digitalPinLabelArray[x] = new javax.swing.JLabel(); // populate label array
        digitalPinLabelArray[x].setText("Pin " + (x +2));
        digitalPinPanel.add(digitalPinLabelArray[x]); // add label to panel
        for(int y = 0; y < 2; y++){
            digitalPinRadioButtonArray[x][y] = new javax.swing.JRadioButton(); // populate radio button array
            digitalPinRadioButtonArray[x][y].addActionListener(new ActionListener() {

                public void actionPerformed(ActionEvent e)
                {
                    //Execute when button is pressed
                    System.out.println("You clicked the button");
                    checkOnOutputs();
                }
            }
        );

        if (y == 0) {digitalPinRadioButtonArray[x][y].setText("Input");}
        if (y == 1) {digitalPinRadioButtonArray[x][y].setText("Output"); digitalPinRadioButtonArray[x][y].setSelected(true);
        }

        digitalPinGroupArray[x].add(digitalPinRadioButtonArray[x][y]); // assign radio buttons to group
        digitalPinPanel.add(digitalPinRadioButtonArray[x][y]); // add buttons to panel
    }

}

jPanel3.setBorder(javax.swing.BorderFactory.createTitledBorder("Generated Boxes"));
digitalPinOutputArray = new javax.swing.JCheckBox[digitalPinTotal];

for(int x = 0; x < digitalPinTotal ; x++) {
    digitalPinOutputArray[x] = new javax.swing.JCheckBox();
    digitalPinOutputArray[x].setText("Output Pin " + (x+2));
    digitalPinOutputArray[x].addActionListener(new ActionListener() {

        public void actionPerformed(ActionEvent e)
        {
            //Execute when button is pressed
            createOutputChars();
        }
    });
    jPanel3.add(digitalPinOutputArray[x]);

}

jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("Analog Pin State"));

jProgressBar1.setMaximum(1024);
jProgressBar1.setToolTipText("");
jProgressBar1.setString(Integer.toString(jProgressBar1.getValue()));
jProgressBar1.setStringPainted(true);

jProgressBar2.setMaximum(1024);
jProgressBar2.setString(Integer.toString(jProgressBar2.getValue()));
jProgressBar2.setStringPainted(true);

jProgressBar3.setMaximum(1024);
jProgressBar3.setString(Integer.toString(jProgressBar3.getValue()));
jProgressBar3.setStringPainted(true);

jProgressBar4.setMaximum(1024);
jProgressBar4.setString(Integer.toString(jProgressBar4.getValue()));
jProgressBar4.setStringPainted(true);

jProgressBar5.setMaximum(1024);
jProgressBar5.setString(Integer.toString(jProgressBar5.getValue()));
jProgressBar5.setStringPainted(true);

jProgressBar6.setMaximum(1024);
jProgressBar6.setString(Integer.toString(jProgressBar6.getValue()));
jProgressBar6.setStringPainted(true);

jLabel1.setText("Pin A0");

jLabel2.setText("Pin A1");

jLabel3.setText("Pin A6");

jLabel4.setText("Pin A7");

jLabel5.setText("Pin A3");

jLabel6.setText("Pin A2");

jLabel7.setText("Pin A4");

jLabel8.setText("Pin A5");

jProgressBar7.setMaximum(1024);
jProgressBar7.setToolTipText("");
jProgressBar7.setString(Integer.toString(jProgressBar7.getValue()));
jProgressBar7.setStringPainted(true);

jProgressBar8.setMaximum(1024);
jProgressBar8.setToolTipText("");
jProgressBar8.setString(Integer.toString(jProgressBar8.getValue()));
jProgressBar8.setStringPainted(true);

javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
jPanel2.setLayout(jPanel2Layout);
jPanel2Layout.setHorizontalGroup(
    jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
    .addGroup(jPanel2Layout.createSequentialGroup()
        .addContainerGap()
        .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel7)
                    .addComponent(jProgressBar1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jProgressBar5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jProgressBar6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel1)
                    .addComponent(jLabel2)
                    .addComponent(jProgressBar2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel8)
                    .addComponent(jLabel5)
                    .addComponent(jLabel3)
                    .addComponent(jProgressBar7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jProgressBar3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(18, Short.MAX_VALUE))
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel6)
                    .addComponent(jProgressBar4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel4)
                    .addComponent(jProgressBar8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(0, 0, Short.MAX_VALUE))))
);
jPanel2Layout.setVerticalGroup(
    jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
    .addGroup(jPanel2Layout.createSequentialGroup()
        .addContainerGap()
        .addComponent(jLabel1)
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addComponent(jProgressBar1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addGap(4, 4, 4)
        .addComponent(jLabel2)
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addComponent(jProgressBar2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addComponent(jLabel6)
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
        .addComponent(jProgressBar3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addComponent(jLabel5)
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addComponent(jProgressBar4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addComponent(jLabel7)
        .addGap(9, 9, 9)
        .addComponent(jProgressBar5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addComponent(jLabel8)
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addComponent(jProgressBar6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addComponent(jLabel3)
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addComponent(jProgressBar7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addComponent(jLabel4)
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addComponent(jProgressBar8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addContainerGap(65, Short.MAX_VALUE))
);

javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
    layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
    .addGroup(layout.createSequentialGroup()
        .addContainerGap()
        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        .addGap(18, 18, 18)
        .addComponent(digitalPinPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 159, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addContainerGap(306, Short.MAX_VALUE))
);
layout.setVerticalGroup(
    layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
    .addGroup(layout.createSequentialGroup()
        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
            .addGroup(layout.createSequentialGroup()
                .addGap(23, 23, 23)
                .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGap(18, 18, 18)
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
            .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(digitalPinPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
        .addContainerGap())
);

digitalPinPanel.getAccessibleContext().setAccessibleName("");

pack();
}// </editor-fold>

private void digitalPinPanelMouseReleased(java.awt.event.MouseEvent evt) {                                              



}                                             

private void checkOnOutputs() {
    // if output selected enable checkbox otherwise disable it
    for (int x = 0; x < digitalPinTotal; x++) {

        if (digitalPinRadioButtonArray[x][0].isSelected() == true) {
            digitalPinOutputArray[x].setEnabled(false);
        }

        if (digitalPinRadioButtonArray[x][1].isSelected() == true) {
            digitalPinOutputArray[x].setEnabled(true);
        }

    }
}


/**
 * @param args the command line arguments
 */
public static void main(String args[]) {
    /* Set the Nimbus look and feel */
    //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
    /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
     * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
     */
    try {
        for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
            if ("Windows".equals(info.getName())) {
                javax.swing.UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } catch (ClassNotFoundException ex) {
        java.util.logging.Logger.getLogger(ArduinoGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (InstantiationException ex) {
        java.util.logging.Logger.getLogger(ArduinoGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
        java.util.logging.Logger.getLogger(ArduinoGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (javax.swing.UnsupportedLookAndFeelException ex) {
        java.util.logging.Logger.getLogger(ArduinoGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    }
    //</editor-fold>

    /* Create and display the form */
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new ArduinoGUI().setVisible(true);
        }
    });
}
// Variables declaration - do not modify
private javax.swing.ButtonGroup buttonGroup1;
private javax.swing.JPanel digitalPinPanel;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3;
private javax.swing.JLabel jLabel4;
private javax.swing.JLabel jLabel5;
private javax.swing.JLabel jLabel6;
private javax.swing.JLabel jLabel7;
private javax.swing.JLabel jLabel8;
private javax.swing.JPanel jPanel1;
private javax.swing.JPanel jPanel2;
private javax.swing.JPanel jPanel3;
private javax.swing.JProgressBar jProgressBar1;
private javax.swing.JProgressBar jProgressBar2;
private javax.swing.JProgressBar jProgressBar3;
private javax.swing.JProgressBar jProgressBar4;
private javax.swing.JProgressBar jProgressBar5;
private javax.swing.JProgressBar jProgressBar6;
private javax.swing.JProgressBar jProgressBar7;
private javax.swing.JProgressBar jProgressBar8;
// End of variables declaration
private int digitalPinTotal = 12;
private int analogPinTotal = 8;
private javax.swing.JCheckBox[] digitalPinOutputArray;
private javax.swing.JRadioButton[][] digitalPinRadioButtonArray;
private javax.swing.ButtonGroup[] digitalPinGroupArray;
private javax.swing.JLabel[] digitalPinLabelArray;

private void initCustomComponents() {
    //throw new UnsupportedOperationException("Not yet implemented");
    // create checkbox array
}

private void createOutputChars(){
    byte outputByte1 = 0;
    byte testByte = 1;
    for (int x = 0;x < 8;x++){
        if (digitalPinOutputArray[x].isSelected()) {
           outputByte1 += (byte) (testByte);
        }
        testByte = (byte) (testByte << 1);
    }

    printByteArray(outputByte1);

}


private void printByteArray(int inputByte) {
    // print out 1 or 0
    byte comparison = 0x1;
    for (int x = 0;x < 8;x++)
    {
        if ((inputByte & comparison) > 0) {
            System.out.print("1");
        }
        else {System.out.print("0");}
        comparison = (byte) (comparison << 1);
    }
    System.out.println();
}

}

Upvotes: 1

Views: 1177

Answers (2)

DwB
DwB

Reputation: 38290

There is no sign bit when you are using the byte as an 8 bit value. it is just a sign bit when you use the byte as a number. Here is an example:

public class LearnByte
{
    public static void main(final String[] arguments)
    {
        byte hootBerry;

        hootBerry = 0x10;
        System.out.printf("0x%x\t%d\n", hootBerry, hootBerry);

        hootBerry |= 0x81;
        System.out.printf("0x%x\t%d\n", hootBerry, hootBerry);
    }
}

Upvotes: 0

Durandal
Durandal

Reputation: 20059

Simply ignore the fact that java byte is signed. It only makes a difference for a few operations (most notably relational operators like >).

Bitwise operators (|, & , ^) provide the same bit-pattern result as they would if byte were unsigned.

I would store just the bit number to be controlled to the combo box and set/read bits like this:

public static boolean isBitSet(byte b, int bitNo) {
    return (b & (1 << bitNo) != 0;
}

public static byte setBit(byte b, int bitNo) {
    return (byte) (b | (1 << bitNo));
}

public static byte clearBit(byte b, int bitNo) {
    return (byte) (b & (~(1 << bitNo)));
}

While directly porting C code to java often leads to different behavior due to the lack unsigned types, the difference is not all that large. All unsigned types can be replaced with signed types, it just requires some attention (and knowledge), since some operations need to be expressed differently.

BTW: Nobody will be so patient as to dig through a wall of code generated by a UI-builder. If you have specific questions, provide a short example, best compilable and executable.

Upvotes: 3

Related Questions